HBase (一) 简介

背景

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拥有版本号,默认采用的是插入的时间戳。

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

    《HBase (一) 简介》 image.png

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

    《HBase (一) 简介》 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 , 使用什么作为列名呢? 假设直接使用被跟随者作为列名。格式如下:

《HBase (一) 简介》 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名字越短越好
    原文作者:半夕蝶梦
    原文地址: https://www.jianshu.com/p/c616503b2038
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞