HBase概述
>
* HBase是一个构建在HDFS上的分布式列存储系统
* HBase是基于Google BigTable模型开发的,典型的key/value系统
* HBase是Apache Hadoop生态系统中的重要一员,主要用于海量结构化数据存储
* 从逻辑上讲,HBase将数据按照表、行和列进行存储
* 与hadoop一样,Hbase目标主要依靠横向扩展,通过不断增加廉价的商用服务器,来增加计算和存储能力
HBase表的特点
>
* 大:一个表可以有数十亿行,上百万列
* 无模式:每行都有一个可排序的主键和任意多的列,列可以根据需要动态的增加,同一张表中不同的行可以有截然不同的列
* 面向列:面向列(族)的存储和权限控制,列(族)独立检索
* 稀疏:空(null)列并不占用存储空间,表可以设计的非常稀疏
* 数据多版本:每个单元中的数据可以有多个版本,默认情况下版本号自动分配,是单元格插入时的时间戳
* 数据类型单一:Hbase中的数据都是字符串,没有类型
![]()
HBase数据逻辑视图
![]()
物理存储
>
* Table中所有行都按照row key的字典序排列
* Table在行的方向上分割为多个Region
* Region按大小分割的,每个表开始只有一个region,随着数据增多,region不断增大,当增大到一个阀值的时候,region就会等分会两个新的region,之后会有越来越多的region
* Region是Hbase中分布式存储和负载均衡的最小单元,不同Region分布到不同RegionServer上
如图:
HBase写入数据流程
如下是官方给出的数据架构图:
当client向HRegionServer发起Table.put(put)请求时,会将请求给对应的HRegion实例来处理。
第一步是决定数据是否需要写入由HLog类实现的预写日志中(WAL);
一旦数据被写入WAL中,数据接下来被放到memstore内存模块中。同时还会检查memstore是否已经满了,
如果满了,就会被请求刷写内存数据到磁盘中,由后台另外一个HRegionServer的线程把数据写成HDFS
中的一个新HFile,保存最后的写入序列号,系统就知道那些数据现在被持久化了。
(shell中的flush命令手动持久化内存数据)
HBase读取数据流程
![]()
-ROOT- 和 .meta. 表
>
从存储结构和操作方法的角度来说,-ROOT-、.META.与其他表没有任何区别。
它们与众不同的地方是HBase用它们来存贮一个重要的系统信息:
>
* -ROOT-:记录.META.表的Region信息
* .META.:记录用户表的Region信息
>
其中-ROOT-表本身只会有一个region,这样保证了只需要三次跳转,就能定位到任意region.meta. 表结构
>
逻辑视图如下:
.META.表中每一行记录了一个Region的信息
1). RowKey
RowKey就是Region Name,它的命名形式是TableName,StartKey,TimeStamp.Encoded.
其中 Encoded 是TableName,StartKey,TimeStamp的md5值。
例如:mytable,,1438832261249.ea2b47e1eba6dd9a7121315cdf0e4f67.
表名是mytable,StartKey为空,时间戳是1438832261249,前面三部分的md5是:
echo -n "mytable,,1438832261249" | md5sum # -n选项表示不输出换行符 2ea2b47e1eba6dd9a7121315cdf0e4f67 -
2) Column Family
.META.表有两个Column Family:info 和 historian
其中info包含了三个Column:
- regioninfo:region的详细信息,包括StartKey、EndKey以及Table信息等等
- server:管理该region的 RegionServer 的地址
- serverstartcode:RegionServer 开始托管该region的时间
这个Column Family是用来追踪一些region操作的,例如open、close、compact等。事实证明这非常的麻烦,所以在想出一个更好的解决方案之前我们禁用了此功能。这个列族会保持向后兼容。
综上所述,.META.表中保存了所有用户表的region信息,在进行数据访问时,它是必不可少的一个环节。当Region被拆分、合并或者重新分配的时候,都需要来修改这张表的内容 来保证访问数据时能够正确地定位region。-ROOT- 表结构
当用户表特别大时,用户表的region也会非常多。.META.表存储了这些region信息,也变得非常大,这时.META.自己也需要划分成多个Region,托管到多个RegionServer上。
这时就出现了一个问题:当.META.被托管在多个RegionServer上,如何去定位.META.呢?HBase的做法是用另外一个表来记录.META.的Region信息,就和.META.记录用户表的Region信息一样,这个表就是-ROOT-表。
在 HBase Shell 里对-ROOT-表进行 scan 和 describe :逻辑视图如下:
![]()
可以看出,除了没有historian列族之外,-ROOT-表的结构与.META.表的结构是一样的。另外,-ROOT-表的 RowKey 没有采用时间戳,也没有Encoded值,而是直接指定一个数字。
-ROOT-表永远只有一个Region,也就只会存放在一台RegionServer上。—— 在进行数据访问时,需要知道管理-ROOT-表的RegionServer的地址。这个地址被存在 ZooKeeper 中。