Hbasesplit的三种⽅式和split的过程
在Hbase中split是⼀个很重要的功能,Hbase是通过把数据分配到⼀定数量的region来达到负载均衡的。⼀个table会被分配到⼀个或多个region中,这些region会被分配到⼀个或者多个regionServer中。在⾃动split策略中,当⼀个region达到⼀定的⼤⼩就会⾃动split成两个region。table在region中是按照row key来排序的,并且⼀个row key所对应的⾏只会存储在⼀个region中,这⼀点保证了Hbase的强⼀致性。
在⼀个region中有⼀个或多个stroe,每个stroe对应⼀个column families(列族)。⼀个store中包含⼀个memstore 和 0 或多个store files。每个column family 是分开存放和分开访问的。
Pre-splitting
当⼀个table刚被创建的时候,Hbase默认的分配⼀个region给table。也就是说这个时候,所有的读写请求都会访问到同⼀个regionServer的同⼀个region中,这个时候就达不到负载均衡的效果了,集中的其他regionServer就可能会处于⽐较空闲的状态。解决这个问题可以⽤pre-splitting,在创建table的时候就配置好,⽣成多个region。
在table初始化的时候如果不配置的话,Hbase是不知道如何去split region的,因为Hbase不知道应该那个row key可以作为split的开始点。如果我们可以⼤概预测到row key的分布,我们可以使⽤pre-spliting来帮
助我们提前split region。不过如果我们预测得不准确的话,还是可能导致某个region过热,被集中访问,不过还好我们还有auto-split。最好的办法就是⾸先预测split的切分点,做pre-splitting,然后后⾯让auto-split 来处理后⾯的负载均衡。
Hbase⾃带了两种pre-split的算法,分别是和。如果我们的row key是⼗六进制的字符串作为前缀的,就⽐较适合⽤,作为pre-split的算法。例如,我们使⽤HexHash(prefix)作为row key的前缀,其中Hexhash为最终得到⼗六进制字符串的hash算法。我们也可以⽤我们⾃⼰的split算法。
在hbase shell 下:
hbase org.apache.hadoop.hbase.util.RegionSplitter pre_split_table HexStringSplit -c 10 -f f1
-c 10 的意思为,最终的region数⽬为10个;-f  f1为创建⼀个那么为f1的 column family.
执⾏scan 'hbase:meta' 可以看到meta表中的,
只截取了meta表中的2个region的记录(⼀共10个region),分别是rowkey范围是 '' ''~19999999 和19999999~33333332的region。
我们也可以⾃定义切分点,例如在hbase shell下使⽤如下命令:
create 't1', 'f1', {SPLITS => ['10', '20', '30', '40']}
⾃动splitting
hbase的特性有哪些
当⼀个reion达到⼀定的⼤⼩,他会⾃动split称两个region。如果我们的Hbase版本是0.94 ,那么默认的有三种⾃动split的策略,,还有 .
在0.94版本之前是默认和唯⼀的split策略。当某个store(对应⼀个column family)的⼤⼩⼤于配置值 ‘hbase.hregion.max.filesize’的时候(默认10G)region就会⾃动分裂。
⽽0.94版本中,IncreasingToUpperBoundRegionSplitPolicy 是默认的split策略。
这个策略中,最⼩的分裂⼤⼩和table的某个region server的region 个数有关,当store file的⼤⼩⼤于如下公式得出的值的时候就会split,公式如下
Min (R^2 * “store.flush.size”, “hbase.hregion.max.filesize”)  R为同⼀个table中在同⼀个region server中region的个数。
例如:
store.flush.size 默认值 128MB。
hbase.hregion.max.filesize默认值为10GB 。
如果初始时R=1,那么Min(128MB,10GB)=128MB,也就是说在第⼀个flush的时候就会触发分裂操作。
当R=2的时候Min(2*2*128MB,10GB)=512MB ,当某个store file⼤⼩达到512MB的时候,就会触发分裂。
如此类推,当R=9的时候,store file 达到10GB的时候就会分裂,也就是说当R>=9的时候,store file 达到10GB的时候就会分裂。split 点都位于region中row key的中间点。
KeyPrefixRegionSplitPolicy可以保证相同的前缀的row保存在同⼀个region中。
指定rowkey前缀位数划分region,通过读取 KeyPrefixRegionSplitPolicy.prefix_length  属性,该属性为数字类型,表⽰前缀长度,在进⾏split时,按此长度对splitPoint进⾏截取。此种策略⽐较适合固定前缀的rowkey。当table中没有设置该属性,指定此策略效果等同与使⽤IncreasingToUpperBoundRegionSplitPolicy。
我们可以通过配置 ion.split.policy 来指定split策略,我们也可以写我们⾃⼰的split策略。
强制split
Hbase 允许客户端强制执⾏split,在hbase shell中执⾏以下命令:
split 'forced_table', 'b' //其中forced_table 为要split的table , ‘b’ 为split 点
region splits 执⾏过程:
region server处理写请求的时候,会先写⼊memstore,当memstore 达到⼀定⼤⼩的时候,会写⼊磁盘成为⼀个store file。这个过程叫做memstore flush。当store files 堆积到⼀定⼤⼩的时候,region server 会执⾏‘compact’操作,把他们合成⼀个⼤的⽂件。当每次执⾏完flush 或者compact操作,都会判断是否需要split。当发⽣split的时候,会⽣成两个region A 和 region B但是parent region数据file并不会发⽣复制等操作,⽽是region A 和region B 会有这些file的引⽤。这些引⽤⽂件会在下次发⽣compact操作的时候清理掉,并且当region中有引⽤⽂件的时候是不会再进⾏split操作的。这个地⽅需要注意⼀下,如果当region中存在引⽤⽂件的时候,⽽且写操作很频繁和集中,可能会出现region变得很⼤,但是却不split。因为写操作⽐较频繁和集中,但是没有均匀到每个引⽤⽂件上去,所以region⼀直存在引⽤⽂件,不能进⾏分裂,这篇⽂章讲到了这个情况,总结得挺好的。
虽然split region操作是region server单独确定的,但是split过程必须和很多其他部件合作。region server 在split开始前和结束前通知master,并且需要更新.META.表,这样,客户端就能知道有新的region。在hdfs中重新排列⽬录结构和数据⽂件。split是⼀个复杂的操作。在split region的时候会记录当前执⾏的
状态,当出错的时候,会根据状态进⾏回滚。下图表⽰split中,执⾏的过程。(红⾊线表⽰region server 或者master的操作,绿⾊线表⽰client的操作。)
/hbase/region-in-transition/region-name ⽬录下,创建⼀个znode,状态为SPLITTING.
2.因为master有对 region-in-transition 的znode做监听,所以,mater的得知parent region需要split
问.META.表获取最新的信息,并且更新本地缓存。
11.在split之后,meta和HDFS依然会有引⽤指向parent region. 当compact 操作发⽣在daughter regions中,会重写数据file,这个时候引⽤就会被逐渐的去掉。垃圾回收任务会定时检测daughter regions是否还有引⽤指向parent files,如果没有引⽤指向parent files的话,parent region 就会被删除。
参考连接:
Hbase split
Hbase 官⽅⽂档(region)
split策略
split源码解析

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。