文章目录
- 前言
- 一、RegionSplitPolicy
- 二.IncreasingToUpperBoundRegionSplitPolicy策略:
- 三.SteppingSplitPolicy策略:
- 四.ConstantSizeRegionSplitPolicy策略:
- 五.KeyPrefixRegionSplitPolicy策略:
- 六.DelimitedKeyPrefixRegionSplitPolicy策略:
- 八.BusyRegionSplitPolicy策略
- 总结
前言
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;
}
- 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做了简单的介绍。