HBase源码分析(八) Region 拆分(split)2021SC@SDUSC


前言

HBase Split是hbase根据一定的触发条件和一定的分裂策略将HBase的一个region进行分裂成两个子region并对父region进行清除处理的过程。本文是对
HBase Split的介绍。


一、RegionSplitPolicy

RegionSplitPolicy是一个抽象类,其做为所有Region拆分策略的父类。在2.0.0版本过后默认用的split策略是SteppingSplitPolicy。
org/apache/hadoop/hbase/regionserver/RegionSplitPolicy.java类的getSplitPoint方法, 主要讲解了region分裂的逻辑。
region分割的过程:

首先判断是否有用户自定义的分割点, 如果有, 则用用户自定义的分裂点, 如果没有, 则查找当前region下的szie最大的Hstore, 定义的分裂点。

何为Hstore?

每一个HRegion由多个HStore来组成,一个HStore对应HRegion中的一个列族,一个HStore有一个MemStore和一个系列StoreFiles组成。

HStore最核心的一个service就是合并memstore刷新到到磁盘里面的storefiles,

把多个storefiles合并成为一个storefile,写到hdfs里面,写到hdfs里面的文件称之为hfile。

思考: 何为分割点splitPoint?
没分割之前
在这里插入图片描述

分割之后
在这里插入图片描述

21|90b2aba05fdf438f700305206b9c97ae|201912211740|157694486这个rowkey就是一个splitPoint。

二.IncreasingToUpperBoundRegionSplitPolicy策略:

参数: hbase.increasing.policy.initial.size

/**
   * @return Region max size or {@code count of regions cubed * 2 * flushsize},
   * which ever is smaller; guard against there being zero regions on this server.
   */
  protected long getSizeToCheck(final int tableRegionsCount) {
    // safety check for 100 to avoid numerical overflow in extreme cases
    return tableRegionsCount == 0 || tableRegionsCount > 100
               ? getDesiredMaxFileSize()
               : Math.min(getDesiredMaxFileSize(),
                          initialSize * tableRegionsCount * tableRegionsCount * tableRegionsCount);
  }

}

nitialSize默认值为256M, 每次分割都是 initialSize * tableRegionsCount * tableRegionsCount * tableRegionsCount,tableRegionsCount的三次方

hbase.hregion.max.filesize默认值是10G, 要想达到10G的标准分割, 流程如下:
比如第一次分割: 256M * 1
第二次分割: 256M * 2 ^3 = 2048M // 总的大小达到2048M, 才能进行第二次分割
第三次分割: 256 * 3 ^3 = 6912MB
第四次分割: 256 * 4^3 = 16384MB > 10G 选其中较小的值10G
以后都是按照10G分割

三.SteppingSplitPolicy策略:

是IncreasingToUpperBoundRegionSplitPolicy的子类, 主要是在IncreasingToUpperBoundRegionSplitPolicy做了一个优化, 减少小表产生过多的region。

hbase.hregion.max.filesize默认值是10G, 要想达到10G的标准分割, 流程如下:
比如第一次分割: 256M * 1
以后都是按照10G分割

四.ConstantSizeRegionSplitPolicy策略:

就是每次按照固定的数(hbase.hregion.max.filesize)进行分割, 默认值是按照10G, 当Region的size超过了10G就触发分割条件

五.KeyPrefixRegionSplitPolicy策略:

参数: prefix_split_key_policy.prefix_length

 @Override
  protected byte[] getSplitPoint() {
    byte[] splitPoint = super.getSplitPoint();
    if (prefixLength > 0 && splitPoint != null && splitPoint.length > 0) {
      // group split keys by a prefix
      return Arrays.copyOf(splitPoint,
          Math.min(prefixLength, splitPoint.length));
    } else {
      return splitPoint;
    }
  }
}

KeyPrefixRegionSplitPolicy策略主要就是重写了getSplitPoint方法, 根据rowKey的前缀对数据进行分组,以便于将这些数据分到相同的Region中, 比如rowKey都是16位的,指定前5位是前缀,那么前5位相同的rowKey在进行region split的时候会分到相同的region中。

上图的splitPoint为21|90b2aba05fdf438f700305206b9c97ae|201912211740|157694486, 如果选择ConstantSizeRegionSplitPolicy策略, 指定prefix_split_key_policy.prefix_length=2, 则21为splitPoint, 将前两位相同的rowkey分到相同的region中

六.DelimitedKeyPrefixRegionSplitPolicy策略:

参数: DelimitedKeyPrefixRegionSplitPolicy.delimiter
DelimitedKeyPrefixRegionSplitPolicy和KeyPrefixRegionSplitPolicy有点类似, 将Rowkey的部分前缀做拆分,将其以这些相同前缀的RowKey,写到同一Region中; DelimitedKeyPrefixRegionSplitPolicy不是按照长度区分, 是指定一个分割字符, 比如“|" 。

hbase-site.xml

八.BusyRegionSplitPolicy策略

这个split策略是基于region有多繁忙

默认值

hbase.busy.policy.blockedRequests 0.2 // 代表20%的请求被阻塞

hbase.busy.policy.minAge 600000; // 10 minutes, 代表开始后的10十分钟内不会split

hbase.busy.policy.aggWindow 300000; // 5 minutes 5分钟一个时间窗口, 用来计算阻塞率

1.判断region繁忙的条件

hbase.busy.policy.minAge 代表开始后的这一段时间内不能被split

if (EnvironmentEdgeManager.currentTime() <  startTime + minAge) {
      return false;
    }
  1. hbase.busy.policy.aggWindow 计算在该窗口时间内的阻塞率

阻塞率=这段时间内的阻塞数/这段时间内的请求数

aggBlockedRate =
    (newBlockedReqs - blockedRequestCount) / (newWriteReqs - writeRequestCount + 0.00001f);
 
 
if (curTime - prevTime >= aggregationWindow) {
  blockedRate = aggBlockedRate;
  prevTime = curTime;
  blockedRequestCount = newBlockedReqs;
  writeRequestCount = newWriteReqs;
}

region时间线

——————————————————————>

| | | |

5min 5min 5min, 5分钟一个窗口, 计算每个窗口内的阻塞率

3.计算阻塞率为 上一个窗口的平均阻塞率和当前窗口的阻塞率的加权和

else if (curTime - startTime >= aggregationWindow) {
      // Calculate the aggregate blocked rate as the weighted sum of
      // previous window's average blocked rate and blocked rate in this window so far.
      float timeSlice = (curTime - prevTime) / (aggregationWindow + 0.0f);
      aggBlockedRate = (1 - timeSlice) * blockedRate + timeSlice * aggBlockedRate;

设置方法:

HTableDescriptor tableDesc = new HTableDescriptor(TableName.valueOf(tableNameStr));
tableDesc.setRegionSplitPolicyClassName("org.apache.hadoop.hbase.regionserver.BusyRegionSplitPolicy");
 
#以下配置根据需要适当修改
tableDesc.setValue("hbase.busy.policy.blockedRequests", "0.2");
tableDesc.setValue("hbase.busy.policy.minAge", "600000");
tableDesc.setValue("hbase.busy.policy.aggWindow", "300000");

总结

本文是对八种HBase Split做了简单的介绍。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值