💎一站式轻松地调用各大LLM模型接口,支持GPT4、智谱、星火、月之暗面及文生图 广告
自动拆分有以下策略。 **1. ConstantSizeRegionSplitPolicy**(了解即可) 在 0.94 版本的时候 HBase 只有一种拆分策略。这个策略非常简单,从名字上就可以看出这个策略就是按照固定大小来拆分 Region。控制它的参数是: | hbase.hregion.max.filesize | Region 的最大大小。默认是 10GB| | --- | --- | 当单个 Region 大小超过了 10GB,就会被 HBase 拆分成为 2 个 Region。采用这种策略后的集群中的 Region大小很平均,理想情况下都是5GB。由于这种策略太简单了,所以不再详细解释了。<br/> **2. IncreasingToUpperBoundRegionSplitPolicy**(0.94 版本后默认,需要掌握理解)。 0.94 版本之后,有了 IncreasingToUpperBoundRegionSplitPolicy 策略。这种策略从名字上就可以看出是限制不断增长的文件尺寸的策略。依赖以下公式来计算文件尺寸的上限增长: ```[math] Math.min(tableRegionsCounts^3 * initialSize,defaultRegionMaxFileSize) ``` `tableRegionCount`:表在所有 RegionServer 上所拥有的 Region 数量总和。 `initialSize`:如果定义了 hbase.increasing.policy.initial.size,则使用这个数值;如果没有定义,就用 memstore 的刷写大小的2倍 ,hbase.hregion.memstore.flush.size * 2。 `defaultRegionMaxFileSize` : ConstantSizeRegionSplitPolicy 所用到的hbase.hregion.max.filesize,即 Region 最大大小。 <br/> 假如 hbase.hregion.memstore.flush.size 定义为 128MB,那么文件尺寸的上限增长将是这样: ( 1 ) 刚 开 始 只 有 一 个 region 的 时 候 , 上 限 是 256MB ,因为 `$ 1^3 *128*2=256MB $`。 (2)当有 2 个 region 的时候,上限是 2GB,因为 `$ 2^3 * 128*2=2048MB $`。 (3)当有 3 个文件的时候,上限是 6.75GB,因为 `$ 3^3 * 128 * 2=6912MB $`。 (4)以此类推,直到计算出来的上限达到 hbase.hregion.max.filesize 所定义region 的 默认的10GB。 走势图如下图: ![](https://img.kancloud.cn/9b/65/9b6563ac7f32300c234c65cce7837513_700x415.png) 当 Region 个数达到 4 个的时候由于计算出来的上限已经达到了 16GB,已经大于 10GB 了,所以后面当 Region 数量再增加的时候文件大小上限已经不会增加了。在最新的版本里 IncreasingToUpperBoundRegionSplitPolicy 是默认的配置。 <br/> **3. KeyPrefixRegionSplitPolicy**(扩展内容) 除了简单粗暴地根据大小来拆分,我们还可以自己定义拆分点。KeyPrefixRegionSplitPolicy 是 IncreasingToUpperBoundRegionSplitPolicy 的子类,在前者的基础上,增加了对拆分点(splitPoint,拆分点就是 Region 被拆分处的rowkey)的定义。它保证了有相同前缀的 rowkey 不会被拆分到两个不同的 Region 里面。这个策略用到的参数如下: | `KeyPrefixRegionSplitPolicy.prefix_length` | rowkey 的前缀长度 | | --- | --- | 该策略会根据 KeyPrefixRegionSplitPolicy.prefix_length 所定义的长度来截取rowkey 作为分组的依据,同一个组的数据不会被划分到不同的 Region 上。比如rowKey 都是 16 位的,指定前 5 位是前缀,那么前 5 位相同的 rowKey 在进行 region split 的时候会分到相同的 region 中。用默认策略拆分跟用KeyPrefixRegionSplitPolicy 拆分的区别如下: :-: ![](https://img.kancloud.cn/1e/05/1e05351d6646ec6018c1a2eadd5e6c4a_781x429.png) 默认策略拆分结果图 ![](https://img.kancloud.cn/90/7b/907b50b7a05ab24026a0c3f97a336527_880x491.png) KeyPrefixRegionSplitPolicy(前 2 位)拆分结果图 <br/> 如果你的所有数据都只有一两个前缀,那么 KeyPrefixRegionSplitPolicy 就无效了,此时采用默认的策略较好。如果你的前缀划分的比较细,你的查询就比较容易发生跨 Region 查询的情况,此时采用 KeyPrefixRegionSplitPolicy 较好。<br/> 所以这个策略适用的场景是:数据有多种前缀。查询多是针对前缀,比较少跨越多个前缀来查询数据。 <br/> **4. DelimitedKeyPrefixRegionSplitPolicy**(扩展内容) 该策略也是继承自 IncreasingToUpperBoundRegionSplitPolicy,它也是根据你的 rowkey 前缀来进行切分的。唯一的不同就是:KeyPrefixRegionSplitPolicy 是根据 rowkey 的固定前几位字符来进行判断,而DelimitedKeyPrefixRegionSplitPolicy是根据分隔符来判断的。有时候 rowkey 的前缀可能不一定都是定长的,比如你拿服务器的名字来当前缀,有的服务器叫 host12 有的叫 host1。这些场景下严格地要求所有前缀都定长可能比较难,而且这个定长如果未来想改也不容易。 DelimitedKeyPrefixRegionSplitPolicy 就给了你一个定义长度字符前缀的自由。使用这个策略需要在表定义中加入以下属性: ``` DelimitedKeyPrefixRegionSplitPolicy.delimiter:前缀分隔符 ``` 比如你定义了前缀分隔符为`_`,那么 host1_001 和 host12_999 的前缀就分别是 host1 和 host12。 <br/> **5. BusyRegionSplitPolicy**(扩展内容) 此前的拆分策略都没有考虑热点问题。所谓热点问题就是数据库中的Region 被访问的频率并不一样,某些 Region 在短时间内被访问的很频繁,承载了很大的压力,这些 Region 就是热点 Region。BusyRegionSplitPolicy 就是为了解决这种场景而产生的。它是如何判断哪个 Region 是热点的呢,首先先要介绍它用到的参数: **`hbase.busy.policy.blockedRequests`**:请求阻塞率,即请求被阻塞的严重程度。取值范围是 0.0~1.0,默认是 0.2,即 20%的请求被阻塞的意思。 **`hbase.busy.policy.minAge`**:拆分最小年龄,当 Region 的年龄比这个小的时候不拆分,这是为了防止在判断是否要拆分的时候出现了短时间的访问频率波峰,结果没必要拆分的 Region 被拆分了,因为短时间的波峰会很快地降回到正常水平。单位毫秒,默认值是 600000,即 10 分钟。 **`hbase.busy.policy.aggWindow`**:计算是否繁忙的时间窗口,单位毫秒,默认值是 300000,即 5 分钟。用以控制计算的频率。计算该 Region 是否繁忙的计算 方法如下: ``` 如果"当前时间–上次检测时间>=hbase.busy.policy.aggWindow",则进行如下计算: 这段时间被阻塞的请求/这段时间的总请求=请求的被阻塞率(aggBlockedRate) 如果"aggBlockedRate > hbase.busy.policy.blockedRequests",则判断该 Region为繁忙。 ``` 如果你的系统常常会出现热点 Region,而你对性能有很高的追求,那么这种策略可能会比较适合你。它会通过拆分热点 Region 来缓解热点 Region 的压力,但是根据热点来拆分 Region 也会带来很多不确定性因素,因为你也不知道下一个被拆分的 Region 是哪个。 <br/> **6. DisabledRegionSplitPolicy** 这种策略其实不是一种策略。如果你看这个策略的源码会发现就一个方法shouldSplit,并且永远返回 false。所以设置成这种策略就是 Region 永不自动拆分。<br/> 如果使用 DisabledRegionSplitPolicy 让 Region 永不自动拆分之后,你依然可以通过手动拆分来拆分 Region。<br/> 这个策略有什么用?无论你设置了哪种拆分策略,一开始数据进入 Hbase的时候都只会往一个 Region 塞数据。必须要等到一个 Region 的大小膨胀到某个阀值的时候才会根据拆分策略来进行拆分。但是当大量的数据涌入的时候,可能会出现一边拆分一边写入大量数据的情况,由于拆分要占用大量 IO,有可能对数据库造成一定的压力。如果你事先就知道这个 Table 应该按怎样的策略来拆分Region 的话,你也可以事先定义拆分点(SplitPoint)。所谓拆分点就是拆分处的rowkey,比如你可以按 26 个字母来定义 25 个拆分点,这样数据一到 HBase 就会被分配到各自所属的 Region 里面。这时候我们就可以把自动拆分关掉,只用手动拆分。