Region拆分与合并

我们都知道,Hbase的region是表的一部分,当表比较大的时候,如果还是一个Region的话,会怎样呢?当我们读取数据的时候是不是效率比较低呢?因此,我们必须对Region进行合理拆分,这也是优化性能的一部分吧。

Region拆分分为两种自动拆分和手动拆分

1.自动拆分

1.1.ConstantSizeRegionSplitPolicy

顾名思义,不变大小region拆分策略,就是按照固定的大小进行拆分Region,用到的唯一参数就是

hbase.hregion.max.filesize  // region的最大大小默认10G

当单个Region超过了10G,则会被拆分成2个Region,因此这个策略拆分Region拆分得比较平均。
不过这个策略是Hbase0.94版本用到的,比较简单

1.2.IncreasingToUpperBoundRegionSplitPolicy

0.94版本之后地默认策略。
从字面上看就是限制Region不断增长得拆分策略。
比如我们的Hbase地以恶搞Region大小是128M,第二个是256M,第三个就是512M……这种策略就是应对这种场景的。
依赖一下公式进行计算

 Math,min(tableRegionCount ^3 *initialSize,defaultRegionMaxFileSize)

tableRegionCount 是Region的数量 initialSize是初始化的大小

如果你定义了hbase.increasing.policy.initial.size,那么就是这个值,否则就是memstore的刷写大小2倍,即hbase.hregion.memstore.flush.size * 2。

defaultRegionMaxFileSize默认10G,就是上面的那个策略用到的

eg:
假如hbase.hregion.memstore.flush.size 为128M
当有第一个文件的时候,大小为 1 ^ 3 *128 =128M
当有第一个文件的时候,大小为 2 ^ 3 *128 =2048M
当有第一个文件的时候,大小为 3^ 3 *128 =6912M
依此类推,直到到达上限defaultRegionMaxFileSize的10G(default)

1.3.KeyPrefixRegionSplitPolicy

KeyPrefixRegionSplitPolicy是IncreasingToUpperBoundRegionSplitPolicy的子类,在IncreasingToUpperBoundRegionSplitPolicy基础上增加了对拆分点splitPoint,就是Region被拆分的rowkey)的定义

保证了具有相同前缀的rowkey可以拆分到相同的Region中
用到的参数是
KeyPrefixRegionSplitPolicy.prefix_length rowkey:前缀长度
根据此参数的的长度截取rowkey作为分组的依据,同一个组的rowkey不会被拆分到不同的Region中

如果你的数据rowkey前缀比较少,还是选择默认的比较好
如果你的rowkey有多种,并且查询的话,主要针对rowkey,则选择此策略

1.4.DelimitedKeyPrefixRegionSplitPolicy

这个策略和KeyPrefixRegionSplitPolicy比较类似,就是此策略是根据分隔符进行拆分,在某些业务场景下,我们的rowkey可能是不定长的,但是都会有相同的分隔符,比如rowkey ldd_1 l,lddqqqqqaa_2等
用到的参数是
DelimitedKeyPrefixRegionSplitPolicy.delimiter:前缀分隔符

1.5.BusyRegionSplitPolicy

热点策略,上述介绍的策略没有提到热点问题。
什么是热点呢?就是你的Hbase,有的Region访问频次比较高,有点比较低,甚至有点都没有访问。那些在短时间内,访问频次比较高的Region就是被称为热点的Region。
用到的参数:
hbase.busy.policy.blockedRequests 请求阻塞率,表示请求被阻塞的严重程度。取值范围一般在0.0~1.0之间,默认是0.2

hbase.busy.policy.minAge:拆分最小年龄,当拆分的Region的年龄比这个小的时候则不进行拆分,为防止有的Region出现短暂的热点现象,单位是ms默认是600000即十分钟

hbase.busy.policy.aggWindow 计算是否繁忙的窗口,单位是ms,默认是300000,五分钟。用以控制计算的频率

那么怎样判定一个Region是否繁忙呢?
计算方法如下:

如果当前时间 - 上次被检测的时间 >= hbase.busy.policy.aggWindow则进行下一个计算
这段时间被阻塞的请求 / 这段时间的总请求 = aggBlockedRate(请求被阻塞率)
如果aggBlockedRate > hbase.busy.policy.blockedRequests 则判定此Region为热点
但是此策略一般用得比较少,根据热带你进行拆分Region有很多不确定的因素,因为你不知道下一个要拆分的Region是哪一个。

如果你的系统出现热点的频次比较高,并且对性能有很高的要求,此策略也是一种不错的选择

1.6.DisabledRegionSplitPolicy

次拆分策略就是禁止自动拆分。
为什么要禁止自动拆分呢?
考虑一下这个情况:
一开始写入数据时,是往一个Region写入数据,当你的Region慢慢增大到阈值的时候,才会根据自动拆分的某个策略进行拆分。当是如果如果你的Region有大量数据进行读写时候,可能会出现一边写,一边进行拆分的情况,会占用大量的IO资源。如果有这种情况发生,并且你已经知道 这个Table的拆分策略的话,可以使用该测率进行手动拆分

使用此策略之后,你可以进行手动拆分
手动拆分有两种情况,一个是预拆分(pre-splitting),一个是强制拆分(forced-splitting)

1.7.预拆分

预拆分(pre-splitting)就是在建表的时候就定义好了拆分点的算法
org.apache.hadoop.hbase.util.RegionSplitter类来创建表,并传入
拆分点算法就可以在建表的同时定义拆分点算法
eg:

[root@hdfa028 bin]# ./hbase org.apache.hadoop.hbase.util.RegionSplitter mytable_pre_split HexStringSplit -c 10 -f info
mytable_pre_split:我们指定要新建的表名。
HexStringSplit:指定的拆分点算法为HexStringSplit。
-c:要拆分的Region数量。
-f:要建立的列族名称

在这里插入图片描述

拆分后的startKey和endKey:

在这里插入图片描述

下面说一下拆分算法:

1.7.1. HexStringSplit

上面的预拆分的例子就采用了这个拆分算法
此拆分算法有一个参数
n ==>要拆分的Region的数量

HexStringSplit把数据从“00000000”到“FFFFFFFF”之间的数据
长度按照n等分之后算出每一段的起始rowkey和结束rowkey,以此作为
拆分点。

1.7.2. UniformSplit

UniformSplit有点像HexStringSplit 的byte版,唯一不同的是起始和结束不是String而是byte[]

起始rowkey是ArrayUtils.EMPTY_BYTE_ARRAY。
结束rowkey是new byte[] {xFF, xFF, xFF, xFF, xFF, xFF,xFF, xFF}。

最后调用Bytes.split方法把起始rowkey到结束rowkey之间的长度n
等分,然后取每一段的起始和结束作为拆分点。
默认的拆分点算法就这两个。你还可以通过实现SplitAlgorithm接
口实现自己的拆分算法。或者干脆手动定出拆分点。

手动指定拆分点的方法就是在建表的时候跟上SPLITS参数,比如:

hbase(main):009:0> create 'test','info1',SPLITS=>['111','222','333']

在这里插入图片描述
图片中的出现的字段解释:

1.rowkey中第一个分隔符前存的是表名

2.第二分隔符前存的是region的第一个rowKey
1)如果这个地方为空的话,表明这是table的第一个region。并且如果一个region中startkey和endkey都为空表明这个table只有一个region;
2)在meta表中,startkey 靠前的region会排在startkey 靠后的region前面。(Hbase中的keys按照字段顺序排序的)
3.region id:region的id,通常基于region创建时的timestamp,之后的以字母开头的是region的hash值
4.regioninfo:HRegion的序列化值
5.server:服务器的地址和端口
6.serverstartcode:服务开始的timestamp,即服务器启动码

1.8.强制拆分

你可以idui运行一段时间的Region进行强制拆分

拆分的调用方式为:

split ‘tableName’
split ‘namespace:tableName’
split ‘regionName’ # format: ‘tableName,startKey,id’
split ‘tableName’, ‘splitKey’
split ‘regionName’, ‘splitKey’

eg:
test,111,1573127932558.f9c10d394ee6d9b21fca614996285ea0Region从新的拆分点999处拆成2个Region。

在这里插入图片描述

在这里插入图片描述

推荐:
一开始可以先定义拆分点,但是当数据开始工作起来后会出现热点
不均的情况,所以推荐的方法是:
(1)用预拆分导入初始数据。
(2)然后用自动拆分来让HBase来自动管理Region。
建议:不要关闭自动拆分。

具体情况具体分析吧

2.Region的合并

前面奖励Region的拆分,现在是合并。
合并的木木丁更多的是维护以及节省资源
当你 删除了大量数据后,大量Region只有一点数据,比较适合合并,这样的话,减少RegionServer资源节省成本,以及提高你查询的效率

2.1.通过Merge 类进行合并

合并之前Hbase和HGegionServer必须处于离线状态
2019-11-07 20:38:43,322 FATAL [main] util.Merge: HBase cluster must be off-line, and is not. Aborting.
关掉Hbase之后再次运行
./hbase org.apache.hadoop.hbase.util.Merge test test,111,1573127932558.f9c10d394ee6d9b21fca614996285ea0. test,222,1573127932558.5d80eb76b85dda5c8e321c3397b46c55.
查看结果:没有了222
在这里插入图片描述

这种方式被称之为冷合并,因为再合并之前必须把HMaster和HReserver停掉才可以
接下来说一下热启动

2.2.热合并

热合并需要在shell里面进行
在这里插入图片描述
接下来以例子,把Region111和333进行合并
热合并需要传参是Region的hash值
比如:test,111,1573130721371.17eeb37374ea7dc28567ebc536270729.
17eeb37374ea7dc28567ebc536270729就是Region的hash值

hbase(main):002:0> merge_region ‘17eeb37374ea7dc28567ebc536270729’,‘a08a009da28e344b460b9181442d1c83’
在这里插入图片描述
如果出现了以下错误信息,说明有Region处于离线状态,使用shell的assign命令上线该Region再次运行命令即可
在这里插入图片描述

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值