本文系转载,若有侵权,请联系我:likui0913@gmail.comhtml
在 HBase 中,Region 是有效性和分布的基本单位,这一般也是咱们在维护时能直接操做的最小单位。好比当一个集群的存储在各个节点不均衡时,HMaster 即是经过移动 Region 来达到集群的平衡。或者某一个 Region 的请求太高时,经过分裂 Region 来分散请求。或者咱们能够指定 Region 的 startKey 和 endKey 来设计它的数据存放范围等等。apache
因此,HBase 在读写数据时,都须要先找到对应的 Region,而后再经过具体的 Region 进行实际的数据读写。缓存
客户端在访问 Region 中的数据以前,须要先经过 HMaster 肯定 Region 的位置,而 HMaster 则将全部 Region 的元信息都保存在 hbase:meta 中。服务器
Meta 表是一个特殊的 HBase 表,它保存了集群中全部 Region 的列表,它的地址被存储在 Zookeeper 中。其表结构以下:数据结构
- RowKey:
- Region Key 格式([table],[region start key],[region id])
- Values:
- info:regionInfo (序列化的.META.的HRegionInfo实例)
- info:server(保存.META.的RegionServer的server:port)
- info:serverStartCode(保存.META.的RegionServer进程的启动时间)
根据 Meta 表中的数据,能够肯定客户端所访问的 RowKey 所处的实际位置。ide
客户端第一次读取或写入 HBase 时将发生如下步骤:性能
1) 客户端从 Zookeeper 获取存储 META 表的 Region 服务器地址; 2) 客户端查询 META 表所在服务器来获取与想要访问的行键相对应的 RegionServer 地址,而后客户端将这些信息与 META 表位置一块儿缓存; 3) 客户端从对应的 RegionServer 获取指定行;ui
对于以后的读取,客户端使用缓存的信息来检索 META 的位置和已经读取过的行键位置信息。随着时间的推移,它将不须要查询 META 表,直到因为某个 Region 已经移动或丢失,客户端才会从新查询并更新缓存。spa
在初次读取写入时,客户端已经缓存了 META 表的信息,同时由于在 HBase 中数据是按行键有序排列的,因此客户端能过经过将要写入数据的行键和缓存信息直接找到对应的 RegionServer 和 Region 位置。那么当客户端发出 Put 请求直到数据真正写入磁盘,它将主要通过如下步骤:设计
1) 将数据写入预写日志 WAL 2) 写入并排序 MemStore 缓存数据 3) 刷新缓存中的数据,并写入到 HFile磁盘
当客户端发出 Put 请求时,HBase 首先会将数据写入预写日志:
一旦数据写入 WAL 成功后,数据将被放入 MemStore 中,而后将 Put 请求确认返回给客户端。客户端接收到确认信息后,对于客户端来讲,这次操做便结束了。
数据放入 MemStore 中后,HBase 不会当即刷新数据到磁盘,而是先更新存储数据使其做为有序的 KeyValues 结构,与存储在 HFile 中的结构相同,并等待 MemStore 累积到足够的数据时才会刷新数据以写入磁盘。
当 MemStore 累积到足够的数据时,整个有序的数据集将被写入 HDFS 中的一个新的 HFile 文件。至此,客户端从发出 Put 请求到数据持久化的过程才算是真正的完成。
根据 HBase 的 RegionServers 的结构可知:在 HBase 中,与一行数据相对应的 KeyValue 单元格可能位于多个位置,好比:行单元格(row cells)已经保存在 HFiles 中,最近更新的单元格位于 MemStore 中,最近读取的单元格位于 BlockCache 中。因此当客户端读取一行数据时,HBase 须要将这些数据合并以获得最新的值。
HBase 将经过如下步骤来合并 BlockCache、MemStore 和 HFile 中的数据:
1) 首先,扫描程序查找 BlockCache 中的行单元格(读取缓存)。最近读取的 keyValue 被缓存在这里,而且当须要使用内存时,清除掉最近使用最少的数据; 2) 而后,扫描器在 MemStore 中查找包含最近写入内存中的缓存数据; 3) 若是扫描器在 MemStore 和 BlockCache 中没有找到全部的行单元格,HBase 将使用 BlockCache 索引和 Bloom 过滤器将 HFile 加载到内存中,它可能包含目标行单元格。
注:Bloom 过滤器肯定的结果并不必定老是准确的,可是否认的结果却必定保证准确。
HBase 的删除操做并不会当即将数据从磁盘上删除,这主要是由于 HBase 的数据一般被保存在 HDFS 之中,而 HDFS 只容许新增或者追加数据文件,因此删除操做主要是对要被删除的数据打上标记。
HFile 中保存了已经排序过的 KeyValue 数据,KeyValue 类的数据结构以下:
{ keylength, valuelength, key: { rowLength, row (i.e., the rowkey), columnfamilylength, columnfamily, columnqualifier, timestamp, keytype (e.g., Put, Delete, DeleteColumn, DeleteFamily) } value }
当执行删除操做时,HBase 新插入一条相同的 KeyValue 数据,可是使 keytype=Delete,这便意味着数据被删除了,直到发生 Major_compaction 操做时,数据才会被真正的从磁盘上删除。