美文网首页我爱编程
HBase (一) 简介

HBase (一) 简介

作者: 半夕蝶梦 | 来源:发表于2018-03-23 09:48 被阅读30次

    背景

    HBase是Apache顶级项目Hadoop的子项目。与传统的RDBMS关系型数据库(Oracle, MySQL, DB2, Hive)等不同,HBase属于NoSQL数据库。 Hbase是对于谷歌提出的BigTable的开源实现。

    定义

    BigTable里的定义:BigTable is a sparse, distributed, persistent mulitdimensional sorted map, indexed by a row key, column key, and a timestamp.
    具体了解下这些定义,就可以了解HBase独特的数据模型。

    • map 键值对
    • sparse 稀疏
    • distributed 分布式
    • persistent 持久化
    • multidimensional 多维度
    • sorted 排序
    • index by a row key, column key, a timestamp 索引

    HBase的数据模型

    HBase里面的结构层级主要有:
    Namespace -> Table -> Row -> Column Family -> Column Qualifier -> Cell
    Namespace:
    Hbase默认有两张表:hbase, default。 hbase存储系统配置。所有不指定Namespace的表格都存储在default下。 当然可以自己创建Namespace, 并建立其下对应的表格。

    Table:
    一样的概念, 只不过table创建的时候只需要指定Column Family(列簇)

    Column Family:
    列簇, 列的最小存储单元

    Column Qualifier:
    列簇的列,每一行的列不需要一致

    Cell:
    由row key, column family, column Qualifier唯一索引的一个值,Cell拥有版本号,默认采用的是插入的时间戳。

    • 用惯用的数据库表格表示下:


      image.png
    • 更直观的键值对表示法:


      image.png

    特点

    其实从以上定义里已经可以发现HBase的特点了,归纳一下

    1. 大,表存储不设限制,支持上亿行, 上百万列
    2. 列簇的概念,拥有面向列的存储和控制
    3. 稀疏,列簇中的列可以拥有不同的列,稀疏化的存储结社空间
    4. 版本控制, 默认插入时的时间戳为cell的版本
    5. 数据统一为不解析的byte数组,没有类型的概念。 包括存储的键和值都是byte
    6. 方便扩展,只需要扩展对应的regionserver就可以。关系型的数据库的扩展取决于server的上限,除非分库分表。

    选择

    什么时候适合?

    1. 当行级别达到一个亿或者十亿级别的时候,适合采用HBase做分布式存储。 其QPS查询性能非常高。
    2. 确定项目不需要考虑RDBMS提供的有用的特性(二级索引,类型化的列, 高级查询)的时候,可以采用。

    部署运行参考官网

    shell 操作

    启动shell界面

    bin/hbase shell
    

    help可以查看支持的命令。 下面列举几个常用的命令:

    1. 查看数据表
      list
    2. 创建数据表
    hbase(main):004:0> create 'test2', 'test_cf'
    0 row(s) in 2.7530 seconds
    
    => Hbase::Table - test2
    
    1. 插入数据
    hbase(main):006:0> put 'test2','row1','test_cf:cq1','value1'
    0 row(s) in 1.9330 seconds
    hbase(main):008:0> scan 'test2'
    ROW                                    COLUMN+CELL                                                                                                   
     row1                                  column=test_cf:cq1, timestamp=1521603395109, value=value1                                                     
    1 row(s) in 0.0400 seconds
    
    hbase(main):009:0> get 'test2', 'row1'
    COLUMN                                 CELL                                                                                                          
     test_cf:cq1                           timestamp=1521603395109, value=value1                                                                         
    1 row(s) in 0.1450 seconds
    
    
    1. 获取表数据
      get
    2. 全表扫描
      scan
    scan 'hbase:meta'
    scan 'hbase:meta',{COLUMNS => 'info:regioninfo'}
    scan 'ns1:t1',{COLUMNS=>['c1','c2'],LIMIT=>10,STARTROW=>'xyz'}
    scan 't1',{COLUMNS=>'c1',TIMERANGE=>[1303668804,1303668904]}
    scan 't1',{REVERSED=>true}
    scan 't1',{
        ROWPREFIXFILTER=>'row2',
        FILTER=>"(QualifierFilter(>=,'binary:xyz')) 
        AND (TimestampsFilter(123,456))"}
    scan 't1',{FILTER => org.apache.hadoop.hbase.filter.ColumnPaginationFilter.new(1,0)}
    scan 't1',{CONSISTENCY=>'TIMELINE'}
    
    设置操作属性:
    scan 't1',{COLUMNS => ['c1','c2'],ATTRIBUTES=>{'mykey'=>'myvalue'}}
    scan 't1',{COLUMNS=>['c1','c2'],AUTHORIZATIONS=>['PRIVATE','SECRET']}
    有个额外的选项:CACHE_BLOCKS,默认为true
    还有个选项:RAW,返回所有cells(包括删除的markers和uncollected deleted cells,不能用来选择特定的columns,默认为default)
    如:scan 't1',{RAW=>true,VERSIONS=>10}
    
    1. 删除数据表
      disable 'test' #先要disable才能drop
      drop 'test'
    2. 查看namespace
    hbase(main):003:0> list_namespace
    NAMESPACE                                                                                                                                            
    default                                                                                                                                              
    hbase                                                                                                                                                
    2 row(s) in 0.3480 seconds
    
    

    案例学习

    参考来自文章
    假设社交网站有一个user表,包含user_id, user_name。 需要设计一个关注的功能。
    该功能有以下几点操作

    • 读操作
    1. user 关注了哪些人
    2. 给定的user A 是否关注user B
    3. 哪些人在关注user A
    • 写操作
    1. 用户关注了一个用户
    2. 用户取消对一个用户的关注

    传统的关系型数据库的设计一般如下:
    设计一张user_follow表. (id, follower_id, folloee_id)。 一旦发生操作,更新或读取user_follower表,此表能满足所有场景。

    那如果切换成HBase的思维呢? (此处例子不一定是最适合HBase的,只是用来查看设计思维)

    设计一:
    设计一个表user_follow, 简单点一个列簇(column family) follow。
    使用userid作为row key , 使用什么作为列名呢? 假设直接使用被跟随者作为列名。格式如下:


    image.png

    此处的列中存储的cell值没有特别用途,直接存个1.
    这个方案能适配读操作中的1,2, 却没法快速的查询3. 改进设计如设计二

    设计二:

    1. 再建立一张新表,保存与设计一关系相反的数据, 即被跟随者作为row key, 保存跟随了他的用户。
    2. 在设计一的基础上再加一个对应的行,用 跟随者 + 被跟随者的名字作为row key.
      这就是一个意识的改变,row key的存储是任意的,无类型的,可以做很多非结构的设计。 但是一般会存储row key的hash值,方便统一长度和计算性能。

    经验法则(rules of thumb)

    • 表设计
    1. region最好大小为10-50G
    2. cf大概一张表1-3个为好,不要用HBASE mimic 模仿关系型数据库
    3. 一个有1或者2个cf的表最好的region值为50-100, Remember that a region is a contiguous segment of a column family
    4. cf名字越短越好

    相关文章

      网友评论

        本文标题:HBase (一) 简介

        本文链接:https://www.haomeiwen.com/subject/mwywqftx.html