hbase分析之split策略

目录

RegionSplitPolicy

IncreasingToUpperBoundRegionSplitPolicy策略:

SteppingSplitPolicy策略:

ConstantSizeRegionSplitPolicy策略:

KeyPrefixRegionSplitPolicy策略:

DelimitedKeyPrefixRegionSplitPolicy策略:

BusyRegionSplitPolicy策略


hbase版本: 2.2.2

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);
  }

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

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

SteppingSplitPolicy策略:

@Override
  protected long getSizeToCheck(final int tableRegionsCount) {
    return tableRegionsCount == 1  ? this.initialSize : getDesiredMaxFileSize();
  }

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

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

那么上图的splitPoint:21|90b2aba05fdf438f700305206b9c97ae|201912211740|157694486, 那么就会按照21作为分割点进行split。

 

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分钟一个时间窗口, 用来计算阻塞率

 
 

判断region繁忙的条件

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

if (EnvironmentEdgeManager.currentTime() <  startTime + minAge) {
  return false;
}

   2. 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");

 

参考: https://blog.csdn.net/fenglibing/article/details/82735979

https://blog.51cto.com/xpleaf/2090433

 

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

千里风雪

你的鼓励是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值