zoukankan      html  css  js  c++  java
  • 大数据学习之HBase

    hbase

    http://hbase.apache.org/index.html

    1.什么是hbase

    HBASE是一个高可靠性、高性能、面向列、可伸缩的分布式存储系统,利用HBASE技术可在廉价PC Server上搭建起大规模结构化存储集群。

    HBASE的目标是存储并处理大型的数据,更具体来说是仅需使用普通的硬件配置,就能够处理由成千上万的行和列所组成的大型数据。

    HBASEGoogle Bigtable的开源实现,但是也有很多不同之处。比如:Google Bigtable利用GFS作为其文件存储系统,HBASE利用Hadoop HDFS作为其文件存储系统;Google运行MAPREDUCE来处理Bigtable中的海量数据,HBASE同样利用Hadoop MapReduce来处理HBASE中的海量数据;Google Bigtable利用Chubby作为协同服务,HBASE利用Zookeeper作为对应。

    1.1与传统数据库的对比

    1、传统数据库遇到的问题:

    1)数据量很大的时候无法存储

    2)没有很好的备份机制

    3)数据达到一定数量开始缓慢,很大的话基本无法支撑

     2、HBASE优势:

    1)线性扩展,随着数据量增多可以通过节点扩展进行支撑

    2)数据存储在hdfs上,备份机制健全

    3)通过zookeeper协调查找数据,访问速度块。

    1.2 hbase集群中的角色

    1、一个或者多个主节点,Hmaster

    2、多个从节点,HregionServer

    1.3 hbase原理

    体系图

     

    HBase的体系结构  

    写流程

    1、 client向hregionserver发送写请求。

    2、 hregionserver将数据写到hlog(write ahead log)。为了数据的持久化和恢复。

    3、 hregionserver将数据写到内存(memstore)

    4、 反馈client写成功。

    数据flush过程

    1、 当memstore数据达到阈值(默认是64M),将数据刷到硬盘,将内存中的数据删除,同时删除Hlog中的历史数据。

    2、 并将数据存储到hdfs中。

    3、 在hlog中做标记点。

    数据合并过程

    1、 当数据块达到4块,hmaster将数据块加载到本地,进行合并

    2、 当合并的数据超过256M,进行拆分,将拆分后的region分配给不同的hregionserver管理

    3、 当hregionser宕机后,将hregionserver上的hlog拆分,然后分配给不同的hregionserver加载,修改.META.

    4、 注意:hlog会同步到hdfs

    hbase的读流程

    1、 通过zookeeper和-ROOT- .META.表定位hregionserver。

    2、 数据从内存和硬盘合并后返回给client

    3、 数据块会缓存

    hmaster的职责

    1、管理用户对Table的增、删、改、查操作;

    2、记录region在哪台Hregion server上

    3、在Region Split后,负责新Region的分配;

    4、新机器加入时,管理HRegion Server的负载均衡,调整Region分布

    5、在HRegion Server宕机后,负责失效HRegion Server 上的Regions迁移。

    hregionserver的职责

    HRegion Server主要负责响应用户I/O请求,向HDFS文件系统中读写数据,是HBASE中最核心的模块。

    HRegion Server管理了很多table的分区,也就是region。

    client职责

    Client

    HBASE Client使用HBASE的RPC机制与HMaster和RegionServer进行通信

    管理类操作:Client与HMaster进行RPC;

    数据读写类操作:Client与HRegionServer进行RPC。

    2.habse安装

    2.1上传

    用工具上传

    2.2解压

    su – hadoop

    tar -zxvf hbase-0.94.6.tar.gz

    2.3重命名

    mv hbase-0.94.6 hbase

    2.4修改环境变量(每台机器都要执行)

    su – root

    vi /etc/profile

    添加内容:

    export HBASE_HOME=/home/hadoop/hbase

    export PATH=$PATH:$HBASE_HOME/bin

    source /etc/proflie

    su - hadoop

    2.5修改配置文件

    上传配置文件

    2.6分发到其他节点

    scp -r /home/hadoop/hbase hadoop@slave1:/home/hadoop/

    scp -r /home/hadoop/hbase hadoop@slave2:/home/hadoop/

    scp -r /home/hadoop/hbase hadoop@slave3:/home/hadoop/

    2.7启动

    注意:启动hbase之前,必须保证hadoop集群和zookeeper集群是可用的。

    start-hbase.sh

    2.8监控

    1、 进入命令行

    hbase shell

    2、 页面监控

    http://master:16010/

    3.hbase数据模型

    3.1 Row Key

    nosql数据库们一样,row key是用来检索记录的主键。访问HBASE table中的行,只有三种方式:

    1.通过单个row key访问

    2.通过row keyrange(正则)

    3.全表扫描

    Row key行键 (Row key)可以是任意字符串(最大长度 是 64KB,实际应用中长度一般为 10-100bytes),在HBASE内部,row key保存为字节数组。存储时,数据按照Row key的字典序(byte order)排序存储。设计key时,要充分排序存储这个特性,将经常一起读取的行存储放到一起。(位置相关性)

    3.2 Columns Family

    列簇 HBASE表中的每个列,都归属于某个列族。列族是表的schema的一部 分(而列不是),必须在使用表之前定义。列名都以列族作为前缀。例如 courses:historycourses:math都属于courses 这个列族。

    3.3 Cell

    {row key, columnFamily, version} 唯一确定的单元。cell中 的数据是没有类型的,全部是字节码形式存贮。

    关键字:无类型、字节码

    3.4 Time Stamp

    HBASE 中通过rowkeycolumns确定的为一个存贮单元称为cell。每个 cell都保存 着同一份数据的多个版本。版本通过时间戳来索引。时间戳的类型是 64位整型。时间戳可以由HBASE(在数据写入时自动 )赋值,此时时间戳是精确到毫秒 的当前系统时间。时间戳也可以由客户显式赋值。如果应用程序要避免数据版 本冲突,就必须自己生成具有唯一性的时间戳。每个 cell中,不同版本的数据按照时间倒序排序,即最新的数据排在最前面。

    为了避免数据存在过多版本造成的的管理 (包括存贮和索引)负担,HBASE提供 了两种数据版本回收方式。一是保存数据的最后n个版本,二是保存最近一段 时间内的版本(比如最近七天)。用户可以针对每个列族进行设置。

    4.hbase命令

    4.1命令的进退

    1hbase提供了一个shell的终端给用户交互

    #$HBASE_HOME/bin/hbase shell 

    2、如果退出执行quit命令

    #$HBASE_HOME/bin/hbase shell

    …… 

    >quit

    4.2命令

    名称

    命令表达式

    创建表

    create '表名', '列族名1','列族名2','列族名N'

    查看所有表

    list

    描述表

    describe  ‘表名’

    判断表存在

    exists  '表名'

    判断是否禁用启用表

    is_enabled '表名'

    is_disabled ‘表名’

    添加记录      

    put  ‘表名’, rowKey, ‘列族 : 列‘  ,  ''

    查看记录rowkey下的所有数据

    get  '表名' , 'rowKey'

    查看表中的记录总数

    count  '表名'

    获取某个列族

    get '表名','rowkey','列族'

    获取某个列族的某个列

    get '表名','rowkey','列族:列’

    删除记录

    delete  ‘表名’ ,‘行名’ , ‘列族:列'

    删除整行

    deleteall '表名','rowkey'

    删除一张表

    先要屏蔽该表,才能对该表进行删除

    第一步 disable ‘表名’ ,第二步  drop '表名'

    清空表

    truncate '表名'

    查看所有记录

    scan "表名"  

    查看某个表某个列中所有数据

    scan "表名" , {COLUMNS=>'列族名:列名'}

    更新记录

    就是重写一遍,进行覆盖,hbase没有修改,都是追加

    5.hbase依赖zookeeper

    1、 保存Hmaster的地址和backup-master地址

    hmaster

    a) 管理HregionServer

    b) 做增删改查表的节点

    c) 管理HregionServer中的表分配

    2、 保存表-ROOT-的地址

    hbase默认的根表,检索表。

    3、 HRegionServer列表

    表的增删改查数据。

    hdfs交互,存取数据。

    6.hbase开发

    6.1 配置

    HBaseConfiguration

    包:org.apache.hadoop.hbase.HBaseConfiguration

    作用:通过此类可以对HBase进行配置

    用法实例:

    Configuration config = HBaseConfiguration.create();

    说明: HBaseConfiguration.create() 默认会从classpath 中查找 hbase-site.xml 中的配置信息,初始化 Configuration

    使用方法:

    static Configuration config = null;

    static {

         config = HBaseConfiguration.create();

         config.set("hbase.zookeeper.quorum", "slave1,slave2,slave3");

         config.set("hbase.zookeeper.property.clientPort", "2181");

    }

    6.2表管理类

    HBaseAdmin

    包:org.apache.hadoop.hbase.client.HBaseAdmin

    作用:提供接口关系HBase 数据库中的表信息

    用法:

    HBaseAdmin admin = new HBaseAdmin(config);

    6.3表描述类

    HTableDescriptor

    包:org.apache.hadoop.hbase.HTableDescriptor

    作用:HTableDescriptor 类包含了表的名字以及表的列族信息

              表的schema(设计)

    用法:

    HTableDescriptor htd =new HTableDescriptor(tablename);

    htd.addFamily(new HColumnDescriptor(“myFamily”));

    6.4列族的描述类

    HColumnDescriptor

    包:org.apache.hadoop.hbase.HColumnDescriptor

    作用:HColumnDescriptor 维护列族的信息

    用法:

    htd.addFamily(new HColumnDescriptor(“myFamily”));

    7.hbase操作

    7.1创建表的操作

    CreateTable(一般我们用shell创建表)

    static Configuration config = null;

    static {

         config = HBaseConfiguration.create();

         config.set("hbase.zookeeper.quorum", "slave1,slave2,slave3");

         config.set("hbase.zookeeper.property.clientPort", "2181");

    }

    HBaseAdmin admin = new HBaseAdmin(config);

    HTableDescriptor desc = new HTableDescriptor(tableName);

    HColumnDescriptor family1 = new HColumnDescriptor(“f1”);

    HColumnDescriptor family2 = new HColumnDescriptor(“f2”);

    desc.addFamily(family1);

    desc.addFamily(family2);

    admin.createTable(desc);

    7.2删除表

    HBaseAdmin admin = new HBaseAdmin(config);

    admin.disableTable(tableName);

    admin.deleteTable(tableName);

    7.3创建一个表的类

    HTable

    包:org.apache.hadoop.hbase.client.HTable

    作用:HTable HBase 的表通信

    用法:

    // 普通获取表

     HTable table = new HTable(config,Bytes.toBytes(tablename);

    // 通过连接池获取表

    Connection connection = ConnectionFactory.createConnection(config);

    HTableInterface table = connection.getTable(TableName.valueOf("user"));

    7.4单条插入数据

    Put

    包:org.apache.hadoop.hbase.client.Put

    作用:插入数据

    用法:

    Put put = new Put(row);

    p.add(family,qualifier,value);

    说明:向表 tablename 添加 “family,qualifier,value”指定的值。

    示例代码:

    Connection connection = ConnectionFactory.createConnection(config);

    HTableInterface table = connection.getTable(TableName.valueOf("user"));

    Put put = new Put(Bytes.toBytes(rowKey));

    put.add(Bytes.toBytes(family), Bytes.toBytes(qualifier),Bytes.toBytes(value));

    table.put(put);

    7.5批量插入

    批量插入

    List<Put> list = new ArrayList<Put>();

    Put put = new Put(Bytes.toBytes(rowKey));//获取put,用于插入

    put.add(Bytes.toBytes(family), Bytes.toBytes(qualifier),Bytes.toBytes(value));//封装信息

    list.add(put);

    table.put(list);//添加记录

    7.6删除数据

    Delete

    包:org.apache.hadoop.hbase.client.Delete

    作用:删除给定rowkey的数据

    用法:

    Delete del= new Delete(Bytes.toBytes(rowKey));

    table.delete(del);

    代码实例

    Connection connection = ConnectionFactory.createConnection(config);

    HTableInterface table = connection.getTable(TableName.valueOf("user"));

    Delete del= new Delete(Bytes.toBytes(rowKey));

    table.delete(del);

    7.7单条查询

    Get

    包:org.apache.hadoop.hbase.client.Get

    作用:获取单个行的数据

    用法:

    HTable table = new HTable(config,Bytes.toBytes(tablename));

    Get get = new Get(Bytes.toBytes(row));

    Result result = table.get(get);

    说明:获取 tablename 表中 row 行的对应数据

    代码示例:

    Connection connection = ConnectionFactory.createConnection(config);

    HTableInterface table = connection.getTable(TableName.valueOf("user"));

    Get get = new Get(rowKey.getBytes());

    Result row = table.get(get);

    for (KeyValue kv : row.raw()) {

    System.out.print(new String(kv.getRow()) + " ");

    System.out.print(new String(kv.getFamily()) + ":");

    System.out.print(new String(kv.getQualifier()) + " = ");

    System.out.print(new String(kv.getValue()));

    System.out.print(" timestamp = " + kv.getTimestamp() + " ");

    }

    7.8批量查询

    ResultScanner

    包:org.apache.hadoop.hbase.client.ResultScanner

    作用:获取值的接口

    用法:

    ResultScanner scanner = table.getScanner(scan);

    For(Result rowResult : scanner){

            Bytes[] str = rowResult.getValue(family,column);

    }

    说明:循环获取行中列值。

    代码示例:

    Connection connection = ConnectionFactory.createConnection(config);

    HTableInterface table = connection.getTable(TableName.valueOf("user"));

    Scan scan = new Scan();

    scan.setStartRow("a1".getBytes());

    scan.setStopRow("a20".getBytes());

    ResultScanner scanner = table.getScanner(scan);

    for (Result row : scanner) {

    System.out.println(" Rowkey: " + new String(row.getRow()));

    for (KeyValue kv : row.raw()) {

         System.out.print(new String(kv.getRow()) + " ");

         System.out.print(new String(kv.getFamily()) + ":");

         System.out.print(new String(kv.getQualifier()) + " = ");

         System.out.print(new String(kv.getValue()));

         System.out.print(" timestamp = " + kv.getTimestamp() + " ");

    }

    }

    8.hbase过滤器

    8.1FilterList

    FilterList 代表一个过滤器列表,可以添加多个过滤器进行查询,多个过滤器之间的关系有:

    与关系(符合所有):FilterList.Operator.MUST_PASS_ALL  

    或关系(符合任一):FilterList.Operator.MUST_PASS_ONE

    使用方法:

    FilterList filterList = new FilterList(FilterList.Operator.MUST_PASS_ONE);   

    Scan s1 = new Scan();  

     filterList.addFilter(new SingleColumnValueFilter(Bytes.toBytes(“f1”),  Bytes.toBytes(“c1”),  CompareOp.EQUAL,Bytes.toBytes(“v1”) )  );  

    filterList.addFilter(new SingleColumnValueFilter(Bytes.toBytes(“f1”),  Bytes.toBytes(“c2”),  CompareOp.EQUAL,Bytes.toBytes(“v2”) )  );  

     // 添加下面这一行后,则只返回指定的cell,同一行中的其他cell不返回  

     s1.addColumn(Bytes.toBytes(“f1”), Bytes.toBytes(“c1”));  

     s1.setFilter(filterList);  //设置filter

     ResultScanner ResultScannerFilterList = table.getScanner(s1);  //返回结果列表

    8.2过滤器的种类

    过滤器的种类:

    列植过滤器SingleColumnValueFilter

          过滤列植的相等、不等、范围等

    列名前缀过滤器—ColumnPrefixFilter

          过滤指定前缀的列名

    多个列名前缀过滤器MultipleColumnPrefixFilter

           过滤多个指定前缀的列名

    rowKey过滤器—RowFilter

          通过正则,过滤rowKey值。

    8.3列值过滤器—SingleColumnValueFilter

    SingleColumnValueFilter 列值判断

    相等 (CompareOp.EQUAL ),

    不等(CompareOp.NOT_EQUAL),

    范围 (e.g., CompareOp.GREATER)…………

    下面示例检查列值和字符串'values' 相等...

    SingleColumnValueFilter f = new  SingleColumnValueFilter(

    Bytes.toBytes("cFamily")              Bytes.toBytes("column"), CompareFilter.CompareOp.EQUAL,

            Bytes.toBytes("values"));

    s1.setFilter(f);

    注意:如果过滤器过滤的列在数据表中有的行中不存在,那么这个过滤器对此行无法过滤。

    8.4列名前缀过滤器—ColumnPrefixFilter

    过滤器ColumnPrefixFilter

    ColumnPrefixFilter 用于指定列名前缀值相等

    ColumnPrefixFilter f = new ColumnPrefixFilter(Bytes.toBytes("values"));

    s1.setFilter(f);

    8.5多个列值前缀过滤器—MultipleColumnPrefixFilter

    MultipleColumnPrefixFilter ColumnPrefixFilter 行为差不多,但可以指定多个前缀

    byte[][] prefixes = new byte[][] {Bytes.toBytes("value1"),Bytes.toBytes("value2")};

    Filter f = new MultipleColumnPrefixFilter(prefixes);

    s1.setFilter(f);

    8.6rowKey过滤器—RowFilter

    RowFilter rowkey过滤器

    通常根据rowkey来指定范围时,使用scan扫描器的StartRowStopRow方法比较好。

    Filter f = new RowFilter(CompareFilter.CompareOp.EQUAL, new RegexStringComparator("^1234")); //匹配以1234开头的rowkey

    s1.setFilter(f);

     

  • 相关阅读:
    Poj 1742 Coins(多重背包)
    Poj 2350 Above Average(精度控制)
    求二进制数中1的个数
    Poj 1659 Distance on Chessboard(国际象棋的走子规则)
    Poj 2411 Mondriaan's Dream(压缩矩阵DP)
    Poj 2136 Vertical Histogram(打印垂直直方图)
    Poj 1401 Factorial(计算N!尾数0的个数——质因数分解)
    poj 2390 Bank Interest(计算本利和)
    Poj 2533 Longest Ordered Subsequence(LIS)
    Poj 1887 Testing the CATCHER(LIS)
  • 原文地址:https://www.cnblogs.com/lq0310/p/9839199.html
Copyright © 2011-2022 走看看