HBase的读写流程和合并拆分机制
一、HBase读写流程
- 读流程
1)Client请求zk找到meta表的Region位置,meta中存储着用户表的Region信息;
2)根据命名空间,表名,rowkey等找到对应的Region信息;
3)根据Region信息请求对应的RegionServer,发送请求,查找对应的Region;
4)先从memStore读取数据,如果没有再从BlackCache中查找数据;Region具有两个内存:一个是memStore,用来写,一个是BC,用来读;
5)如果从BC中还没找到数据,再去读取StoreFile上读取;
6)从storeFile中读取数据不是直接返回给客户端,而是先写到BC,加快后续的查询,再返回给客户端;
- 写流程
1)Client通过zk找到hbase的元数据表,找出对应的HRegionServer(host:port),向HRegionServer发送写请求;
2)Client提交一个put请求到HRegionServer,数据首先会写入到WAL(预写日志,Write ahead Log,HLog)中,当数据写入到WAL(HLog)后,数据会被写到MemStore中,等待刷新到磁盘中;数据写入到MemStore完成后,HRegionServer会给Client发送确认信息;
3)数据被写入Region的MemStore,直到MemStore达到预设的阈值,MemStore中数据被Flush成StoreFile,随着StoreFile不断增多达到某个阈值是会触发Compact合并操作,将多个StoreFile文件合并成一个StoreFile,同时进行版本合并和数据删除;
4)单个StoreFile文件达到默认的大小(10G)会进行split,将当前的Region分裂成两个新的Region,父Region会被下线,新的两个Region会被HMaster分发到不同的RegionServer,使得原来的一个Region压力分流在两个Region上,用户的写操作之进入到内存中便返回,数据增加和删除都是在Compact历程中进行;
二、合并拆分机制
- Flush机制
# 当memStore达到设定的值,默认128M
hbase.hregion.memstore.flush.size = 134217728
# 当memStore中数据超过指定时间,默认是一小时
hbase.regionserver.optionalcacheflushinterval=360000
# Hregionserver的全局memStore大小,默认堆大小是40%
hbase.regionserver.global.memstroe.size=0.4 - 合并机制
1)在Store中,将多个storeFile文件进行合并;删除和更新操作发生再这一过程,仅仅只是做了标记,并不是物理移除,合并频繁;
2)大合并,将所有的storeFile合并为一个大的文件,带有删除标记的数据会被真正的删除,合并频率比较低;
- 拆分策略
# 建表时指定拆分策略
create 't_test', {METADATA => {'SPLIT_POLICY' => 'org.apache.hadoop.hbase.regionserver.IncreasingToUpperBoundRegionSplitPolicy'}, NAME => 'CF'}
1)ConstantSizeRegionSplitPolicy(0.94版本之前):当Region大小大于某个阈值(默认是10G)就会触发切分,一个Region等分为2个Region;但这种策略对于大表和小表没有明显的区分,阈值设置较大对大表比较友好,但是小表就有可能不会触发分裂,极端情况下就一个,当设置较小时,大表会分裂为多个Region,对于集群的使用和管理并不好。
2)IncreasingToUpperBoundRegionSplitPolicy(0.94-2.0):一个Region在达到某个阈值时就会触发切分,但是这个阈值是动态调整的,调整的规则和当前regionserver上的region个数有关系,具体的计算公式为:
RegionCount^3 * 128M * 2, 当region达到该size的时候进行split:
第一次: 1^3 * 256 = 256M
第二次: 2^3 * 256 = 2048M
第三次:3^3 * 256 = 6912M
第四次:4^3 * 256 = 16384 > 10G
后面每次split都是为10G
3)SteppingSplitPolicy(2.0版本默认的切分策略):仍然和RegionCount有关,当region的个数为1时,切分的阈值为flush size * 2,否则为MaxRegionFileSize。
4)KeyPrefixRegionSplitPolicy:根据rowkey的前缀进行分组,相同前缀的rowkey在进行分组时会被分到相同的region中。
5)DelimittedKeyPrefixRegionSplitPolicy:保证相同前缀的数据在同一个Region中,例如rowkey格式为city_log_action,指定delimited为_时,city相同数据在同一个region