Region合并

Region合并的使用场景比较有限,Region上的数据因为TTL过期被删除。这种场景下的Region实际上没有任何存在的意义,称为空闲Region。一旦集群中空闲Region很多,就会导致集群管理运维成本增加。此时,可以使用在线合并功能将这些Region与相邻的Region合并,减少集群中空闲Region的个数。

Region合并的主要流程如下:

  • 1)客户端发送merge请求给Master。
  • 2)Master将待合并的所有Region都move到同一个RegionServer上。
  • 3)Master发送merge请求给该RegionServer。
  • 4)RegionServer启动一个本地事务执行merge操作。
  • 5)merge操作将待合并的两个Region下线,并将两个Region的文件进行合并。
  • 6)将这两个Region从hbase:meta中删除,并将新生成的Region添加到hbase:meta中。
  • 7)将新生成的Region上线。

Region分裂

Region分裂触发策略

  • ConstantSizeRegionSplitPolicy:0.94版本之前默认分裂策略。表示一个Region中最大Store的大小超过设置阈值(hbase.hregion.max.filesize)之后会触发分裂。

  • IncreasingToUpperBoundRegionSplitPolicy:0.94版本~2.0版本默认分裂策略。这种分裂策略总体来看和ConstantSizeRegionSplitPolicy思路相同,一个Region中最大Store大小超过设置阈值就会触发分裂。但是这个阈值并不像ConstantSizeRegionSplitPolicy是一个固定的值,而是在一定条件下不断调整,调整后的阈值大小和Region所属表在当前RegionServer上的Region个数有关系,调整后的阈值等于(#regions)(#regions)(#regions)flush size2

  • SteppingSplitPolicy:2.0版本默认分裂策略。这种分裂策略的分裂阈值也发生了变化,相比IncreasingToUpperBoundRegionSplitPolicy简单了一些,分裂阈值大小和待分裂Region所属表在当前RegionServer上的Region个数有关系,如果Region个数等于1,分裂阈值为flush size*2,否则为MaxRegionFileSize。这种分裂策略对于大集群中的大表、小表会比IncreasingToUpperBoundRegionSplitPolicy更加友好,小表不会再产生大量的小Region。

Region分裂准备工作——寻找分裂点

HBase对于分裂点的定义为:整个Region中最大Store中的最大文件中最中心的一个Block的首个rowkey,如果定位到的rowkey是整个文件的首个rowkey或者最后一个rowkey,则认为没有分裂点。

Region核心分裂流程

HBase将整个分裂过程包装成了一个事务,目的是保证分裂事务的原子性。整个分裂事务过程分为三个阶段:prepare、execute和rollback。

prepare阶段

在内存中初始化两个子Region,具体生成两个HRegionInfo对象,包含tableName、regionName、startkey、endkey等。同时会生成一个transaction journal,这个对象用来记录分裂的进展,具体见rollback阶段。

execute阶段

  • 1)RegionServer将ZooKeeper节点/region-in-transition中该Region的状态更改为SPLITING。
  • 2)Master通过watch节点/region-in-transition检测到Region状态改变,并修改内存中Region的状态,在Master页面RIT模块可以看到Region执行split的状态信息。
  • 3)在父存储目录下新建临时文件夹.split,保存split后的daughter region信息。
  • 4)关闭父Region。父Region关闭数据写入并触发flush操作,将写入Region的数据全部持久化到磁盘。此后短时间内客户端落在父Region上的请求都会抛出异常NotServingRegionException。
  • 5)在.split文件夹下新建两个子文件夹,称为daughter A、daughter B,并在文件夹中生成reference文件,分别指向父Region中对应文件。这个步骤是所有步骤中最核心的一个环节,生成了如下reference文件日志。
  • 6)父Region分裂为两个子Region后,将daughter A、daughter B拷贝到HBase根目录下,形成两个新的Region。
  • 7)父Region通知修改hbase:meta表后下线,不再提供服务。下线后父Region在meta表中的信息并不会马上删除,而是将split列、offline列标注为true,并记录两个子Region
  • 8)开启daughter A、daughter B两个子Region。通知修改hbase:meta表,正式对外提供服务

rollback阶段

如果execute阶段出现异常,则执行rollback操作

Region分裂原子性保证

region分裂是一个比较复杂的过程,涉及父Region中HFile文件分裂、两个子Region生成、系统meta元数据更改等很多子步骤,因此必须保证整个分裂过程的原子性,即要么分裂成功,要么分裂失败,在任何情况下不能出现分裂完成一半的情况。

为了实现原子性,HBase使用状态机的方式保存分裂过程中的每个子步骤状态,这样一旦出现异常,系统可以根据当前所处的状态决定是否回滚,以及如何回滚。遗憾的是,目前实现中这些中间状态都只存储在内存中,一旦在分裂过程中出现RegionServer宕机的情况,有可能会出现分裂处于中间状态的情况,也就是RIT状态。这种情况下需要使用HBCK工具具体查看并分析解决方案。

posted on 2025-08-26 22:31  饺子挺好的  阅读(16)  评论(0)    收藏  举报