转 Hbase 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的算法,分别是 HexStringSplit 和  UniformSplit 。如果我们的row key是十六进制的字符串作为前缀的,就比较适合用HexStringSplit,作为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表中的,

      转	Hbase split的三种方式

 

只截取了meta表中的2个region的记录(一共10个region),分别是rowkey范围是 '' ''~19999999 和19999999~33333332的region。

我们也可以自定义切分点,例如在hbase shell下使用如下命令:

create 't1''f1', {SPLITS => ['10''20''30''40']}

 

自动splitting

 

当一个reion达到一定的大小,他会自动split称两个region。如果我们的Hbase版本是0.94 ,那么默认的有三种自动split的策略,ConstantSizeRegionSplitPolicy,IncreasingToUpperBoundRegionSplitPolicy还有 KeyPrefixRegionSplitPolicy.

 

在0.94版本之前ConstantSizeRegionSplitPolicy 是默认和唯一的split策略。当某个store(对应一个column family)的大小大于配置值 ‘hbase.hregion.max.filesize’的时候(默认10G)region就会自动分裂。

 

而0.94版本中,IncreasingToUpperBoundRegionSplitPolicy 是默认的split策略。

这个策略中,最小的分裂大小和table的某个region server的region 个数有关,当store file的大小大于如下公式得出的值的时候就会split,公式如下

 

Min (R的立方^2 * “hbase.hregion.memstore.flush.size”, “hbase.hregion.max.filesize”)  R为同一个table中在同一个region server中region的个数。

 

例如:

hbase.hregion.memstore.flush.size 默认值 128MB。

hbase.hregion.max.filesize默认值为10GB 。

  • 如果初始时R=1,那么Min(1*1*1*2*128MB,10GB)=128MB,也就是说在第一个flush的时候就会触发分裂操作。

  • 当R=2的时候Min(2*2*2*2*128MB,10GB)=2048MB ,当某个store file大小达到2048MB的时候,就会触发分裂。

  •  如此类推,当R=4的时候,store file 达到10GB的时候就会分裂,也就是说当R>=4的时候,store file 达到10GB的时候就会分裂。

 

split 点都位于region中row key的中间点。

 

KeyPrefixRegionSplitPolicy可以保证相同的前缀的row保存在同一个region中。

指定rowkey前缀位数划分region,通过读取 KeyPrefixRegionSplitPolicy.prefix_length  属性,该属性为数字类型,表示前缀长度,在进行split时,按此长度对splitPoint进行截取。此种策略比较适合固定前缀的rowkey。当table中没有设置该属性,指定此策略效果等同与使用IncreasingToUpperBoundRegionSplitPolicy。

 

我们可以通过配置 hbase.regionserver.region.split.policy 来指定split策略,我们也可以写我们自己的split策略。

 

强制split

 

Hbase 允许客户端强制执行split,在hbase shell中执行以下命令:

 split 'forced_table''b' //其中forced_table 为要split的table , ‘b’ 为split 点
上一篇:photoshop合成动感的牛奶花朵


下一篇:Spring Boot 应用监控