HBase 的核心解决问题为低延时的海量数据集中的随机读写操作。

        HBase(PowerSet 公司) 是 Google 的 BigTable 的开源实现,底层存储引擎是基于 LSM-Tree 数据结构设计的。写入数据时会先写 WAL 日志,再将数据写到写缓存 MemStore 中,MemStore 的内部实现是一个跳表数据结构,等写缓存达到一定规模后或满足其他触发条件才会 Flush 刷写到磁盘,为了提高从文件中查找数据的效率,将内存的数据先按照一定的规则排序,然后刷写到磁盘上。这样就将磁盘随机写变成了顺序写,提高了写性能。每一次刷写磁盘都会生成新的 HFile 文件。

一、存储引擎

1.1 存储引擎 LSM Tree

LSM 树的设计思想非常朴素:将对数据的修改增量保持在内存中,达到指定的大小限制后将这些修改操作批量写入磁盘,不过读取的时候稍微麻烦,需要合并磁盘中历史数据和内存中最近修改操作,所以写入性能大大提升,读取时可能需要先看是否命中内存,否则需要访问较多的磁盘文件。极端的说,基于 LSM 树实现的HBase 的写性能比 MySQL 高了一个数量级,读性能低了一个数量级。LSM 树原理把一棵大树拆分成 N 棵小树,它首先写入内存中,随着小树越来越大,内存中的小树会 flush 到磁盘中,磁盘中的树定期可以做 merge 操作,合并成一棵大树,以优化读性能。

1.2 数据结构跳表
对于 HBase 来说,整体的架构设计就是一个跳表结构;其次,存储在内存中的数据,也是以跳表的数据结构进行存储的!

HBase 的跳表体现在两个方面:
a、HBase 的整体架构

  •  HBase 的一张表叫做 HTable,HTable 按照 Rowkey 全局有序,在全表层面,进行范围分区(【a-c】,【c-g】,【g-l】)每一段叫做 Region 就是一个分区。
  •  每个分区,生成一条索引数据,存储在 meta 表中, meta 当然也有可能变得很大,也需要进行范围分区,也会生成多条元数据。
  • 每个 meta 的分区的元数据,都存储在 root 表中
  • 整体的结构:2 层索引表(meta + root,0.92之后为一层,只有meta表) + 1 层数据(用户表)

b、HBase 的写缓存的数据结构
        写缓存 MemStore:内部实现就是一个 Map : ConcurrentSkipListMap 基于跳表实现的一种兼顾 查询 和 插入效率的一种数据结构

1.3 布隆过滤器

        布隆过滤器(Bloom Filter)是1970年由布隆提出的。它实际上是一个很长的二进制向量和一系列随机映射函数。布隆过滤器可以用于检索一个元素是否在一个集合中。它的优点是空间效率和查询时间都远远超过一般的算法,缺点是有一定的误识别率和删除困难。

        Bloom Filter是一种空间效率很高的随机数据结构,它利用位数组很简洁地表示一个集合,并能判断一个元素是否属于这个集合。Bloom Filter的这种高效是有一定代价的:在判断一个元素是否属于某个集合时,有可能会把不属于这个集合的元素误认为属于这个集合(false positive)。因此,Bloom Filter不适合那些“零错误”的应用场合。而在能容忍低错误率的应用场合下,Bloom Filter通过极少的错误换取了存储空间的极大节省。

二、HBase逻辑表模型

HBase 是一个稀疏的、分布式的、多维排序的 Map。

HBase 是一张四维表!hbase.table.get(rowkey, cf, qualifier, timestamp) = value

HBase是一个超级复杂的map,例如:

table.get(rowkey) = map(cf, map(qualifier, map(timestamp, value)))
 table.get(rowkey, cf) = map(qualifier, map(timestamp, value))
 table.get(rowkey, cf, qualifier) = map(timestamp, value)
 table.get(rowkey, cf, qualifier, timestamp) = value


 

HBase 其实可以理解成是如下结构的 Map:

table = map(rowkey, map(cf, map(qualifier, map(timestamp, value))))
 table = map((rowkey, cf, qualifier, timestamp), value)


 

HBase的存储模型如下:

rowkey

cf

column

timestamp

value

10001

a

 

time1

1

time2

2

b

time1

3

10002

 

a

 

time1

9

time2

8

b

time3

2

c

 

time1

2

time5

9

 可能有这样的说法:有人说 HBase 是列式存储?又有人说 HBase 是行式存储?HBase 逻辑上可以看做是列式存储,物理上其实是行式存储,更严谨的说法是列簇式存储。
列簇式存储的第一个极端: 每个列簇只有一个列,列式存储,HBase 把每个列簇的数据单独存储
列簇式存储的第二个极端:整张表只有一个列簇,包含了所有的列,行式存储。

三、

hbase订单设计 hbase的设计目标_hbase

各个组件的职责:
Client
	负责向 ZooKeeper 发起请求,获取元数据
	维护了一个 MetaCache 用来缓存元数据信息
HMaster
	为 HRegionServer 分配 Region
	负责 HRegionServer 的负载均衡
	发现失效的 HRegionServer 并重新分配其上的 HRegion
HDFS 上的垃圾文件(HBase)回收
	处理 Schema 更新请求(表的创建,删除,修改,列簇的增加等等 DDL 操作,DML请求由 RegionServer 处理)
	如果 HBase 的 HMaster 宕机一段时间?HBase 还能正常工作么?
	HDFS: 主从架构,namenode死亡,HDFS 集群不可用
	HBase:主从架构,HMaster死亡,HBase依然可用(DML功能可用,DDL功能不可用)
HRegionServer
	HRegionServer 维护 HMaster 分配给它的 Region,处理对这些 Region 的 IO 请求
	HRegionServer 负责和底层的文件系统 HDFS 的交互,存储数据到 HDFS
	HRegionServer 负责 Store 中的 HFile 的合并 Compact 工作
	HRegionServer 负责 Split 在运行过程中变得过大的 Region
ZooKeeper
	ZooKeeper 为 HBase 提供 Failover 机制,选举 HMaster,避免单点 HMaster 单点故障问题
	存储所有 Region 的寻址入口:meta 表在哪台服务器上。
	实时监控 HRegionServer 的状态,将 HRegionServer 的上线和下线信息实时通知给 HMaster
	存储 HBase 的 Schema,包括有哪些 Table,每个 Table 有哪些 Column Family
HDFS
	负责存储 HBase 的各个 HRegionServer 上生成的 HFile 数据文件
	负责存储 HBase 的各个 HRegionServer 上生成的 Hlog 日志文件  


补充描述
1. Table 中的所有行都按照 RowKey 的字典序排列。
2. Table 在行的方向上分割为多个 HRegion。
3. HRegion 按大小分割的(默认 10G),每个表一开始只有一个 HRegion,随着数据不断插入表,HRegion 不断增大,当增大到一个阀值的时候,HRegion 就会等分会两个新的 HRegion。当表中的行不断增多,就会有越来越多的 HRegion。
4. HRegion 是 HBase 中分布式存储和负载均衡的最小单元。最小单元就表示不同的 HRegion 可以分布在不同的 HRegionServer 上。但一个 HRegion 是不会拆分到多个 Server 上的。
5. HRegion 虽然是负载均衡的最小单元,但并不是物理存储的最小单元。事实上,HRegion 由一个或者多个 Store 组成,每个 Store 保存一个 Column Family。每个 Strore 又由一个 MemStore 和 0 至多个 StoreFile 组成