Rigion 切分策略
也可以说是切分的时机
- 静态大小切分策略(0.94版本之前)
从名字看是达到一定的大小即开始切割,注意这里是region中的某一个Store的大小超过了阈值(hbase.hregion.max.filesize)
存在的问题
它对大表还算一般友好,因为会被不断的切割,但时间长了后就会产生很多Region
对小表特别不友好,因为它永远不会分割
Region数应该是需要适中就好,太大,数据太分散了会引起RegionServer级别的Flush,这会严重影响读写
太少了,又会降低并行度,比如spark读取的时候
-
上界不断递增策略(0.94版本-2.0版本)
调整规则为region所属表在当前regionserver上的region个数有关系 :(#regions) * (#regions) * (#regions) * flush size * 2,当然阈值并不会无限增大,最大值为用户设置的MaxRegionFileSize。
即region个数的三次方乘以刷新store_file的大小乘以2
上限为hbase.hregion.max.filesize
解决的问题:
这样小表会得到分割,大表也会随着分割的越来越多,阈值越大,解决了大表分割为很多小Region的问题
出现的新问题
小表又被切割了很多小Region
-
两步走策略(2.0版本)
当Region 数为一个时,阈值为flush size *2,其他情况与第一种一样。
如果region个数等于1,切分阈值为flush size * 2,否则为MaxRegionFileSize。
个人觉得这种方式还是存在大表切割很多的问题。
怎么找到切割点
整个region中最大store中的最大文件中最中心的一个block的首个rowkey。这是一句比较消耗脑力的语句,需要细细品味。另外,HBase还规定,如果定位到的rowkey是整个文件的首个rowkey或者最后一个rowkey的话,就认为没有切分点。
所以测试时随便搞几条数是无法切割的
切割流程
主要的三个阶段:
-
Prepare阶段
在内存中生成两个HRegionInfo,记录RegionName ,TableName,StartRowkey,EndRowKey,启动一个事务管理器以方便回滚事务
transaction journal
-
Excute阶段
- zookeeper状态阶段
- 首先在Zookeeper的hbase/region-in_transition下标记分割的Region为分割状态
- ZK的Master检测到以上配置,修改内存中Region的状态
- 临时文件及配置准备阶段
- 首先在父region的目录建立一个.splits的文件夹
- 在下面建立两个文件夹
- 关闭父Region,触发Flush持久化整个region的数据到磁盘,短时不能处理请求
- 在两个子文件夹下生成引用文件
- 引用文件表达父region的标识和父Region的HFile文件,以及split key,一个boolean表达此子region是父region的上半部分吗?
- 父region分裂为两个子region后,将daughter A、daughter B拷贝到HBase根目录下,形成两个新的region
- 服务交换阶段
-
通知元数据表将父Region下线
-
将子Region上线
-
- zookeeper状态阶段
-
RollBack阶段(可选)
基于transaction journal记录,如果发生切割异常将按以下步骤进行回滚
以上过程中一些疑问
-
数据在什么时候进行迁移
Major Compact-
-
怎么保证事务的安全性
2.0之前切割的中间步骤的记录都是在内存中的,一旦宕机,region就会一直处于中间状态
这种情况下需要使用hbck工具进行具体查看并分析解决方案。(这也是看的大佬的文章的答案,并不知晓详细)
-
什么时候删除Region
HMaster启动一个线程定期去处理
http://hbasefly.com/2017/08/27/hbase-split/