HBase表的结构如下:
每个Table由若干个Region组成,每个Region由若干个Store组成(每个列组构成一个Store),每个由一个MemStore和若干个StoreFiles(HFiles)组成,每个StoreFile由若干个Blocks组成。
HBase对表进行split有三种方式:Pre-splitting,Auto splitting,Forced Splits。
Pre-splitting
如果一个节点有过多的读写操作,HBase可能会因为Zookeeper的连接超时而关掉该节点,所以一个良好的策略是将表预分割为固定数量的区域(region),并且这些区域均匀地分布在所有的服务器(regionserver)上,然后让HBase的自动分割功能来处理后面不断增加的数据。RegionSplitter提供三个用于预分割的工具:HexStringSplit、SplitAlgorithm、UniformSplit。其中HexStringSplit和UniformSplit是两个预定义的静态类,可以直接使用;而SplitAlgorithm是一个接口,需要开发人员自己实现相应的分隔策略。如果是以十六进制字符串作为行键rowkey或者行键rowkey的前缀是十六进制字符串,用HexStringSplit就比较合适;UniformSplit会把行键均匀地分割多个部分,如果行将rowkey是随机的字节数组,用UniformSplit就比较合适;或者开发者根据需要实现分割策略。
HBase shell命令示例:
hbase org.apache.hadoop.hbase.util.RegionSplitter test_table HexStringSplit -c 10 -f f1
其中HexStringSplit指明分割策略,-c 10指明要分割的区域数量,-f指明表中的列组,用“:”分割。
或者明确的指明分割点:
create ‘test_table‘, ‘f1‘, SPLITS => [‘a‘, ‘b‘, ‘c‘]
或
echo -e "a\nb\nc" >> /tmp/splits
create ‘test_table‘, ‘f1‘, SPLITSFILE => ‘/tmp/splits‘
Auto splitting
Region的分割操作对于Master不可见的,RegionServer拆分region的步骤是,先将该region下线,然后拆分,将其子region加入到META元信息中,再将他们加入到原本的RegionServer中,最后汇报给Master。 不管是否对表进行了pre-splitting,只要region的大小到达设定的阈值,Hbase都会自动将其split为两个大小相等的region。HBase有如下几种Auto splitting的方法:ConstantSizeRegionSplitPolicy,
IncreasingToUpperBoundRegionSplitPolicy,KeyPrefixRegionSplitPolicy,DelimitedKeyPrefixRegionSplitPolicy。第一个是HBase0.94版本前默认的分割方法,只要region中任一个Store(即一个列族)的大小大于设置的阈值(hbase.hregion.max.filesize
,默认大小是10G),HBase就会将该region分割为两个region。此分割方法适合已经做过pre-splitting且希望每个regionserver的region数量尽可能少的情况。第二个是HBase0.94及其以后版本的默认分割方法,此方法的分割阈值跟同一个regionserver上region的数量有关,Store的大小的最大值取决于公式:Min (R^2 * hbase.hregion.memstore.flush.size, hbase.hregion.max.filesize)
,其中R是同一个regionserver上同一个表的region的数量。这里以hbase.hregion.memstore.flush.size=128M
、hbase.hregion.max.filesize=10G
为例说明,初始时regionserver中只有一个region,那么分割大小为128M,随着region数量的增多分割大小也逐渐增大:512MB, 1152MB, 2GB, 3.2GB, 4.6GB, 6.2GB……。当有9个region时,分隔大小将会超过hbase.hregion.max.filesize
,也就是10G将作为以后的分割大小。对于以上两个分割方法,不管什么时候对表进行分割,总是以最大Store的最大的StoreFile索引的中间作为分割点。对于第三个分割方法,我们可以设置rowkey的前缀长度prefix_split_key_policy.prefix_length
,这样在对表进行分割的时候具有相同前缀的行总是被分割到相同的region。而第四个分割方法保证以分隔符前面的前缀为splitPoint,保证相同RowKey前缀的数据在一个Region中。
Forced Splits
HBase允许我们在HBase shell中对表或者一个region进行分割。示例如下:
split ‘b07d0034cbe72cb040ae9cf66300a10c‘, ‘b‘0 row(s) in 0.1620 seconds
具体操作细节
在hbase-site.xml中配置全局的分割策略
<property>
<name>hbase.regionserver.region.split.policy</name>
<value>org.apache.hadoop.hbase.regionserver.IncreasingToUpperBoundRegionSplitPolicy</value>
</property>
利用Java API对表进行配置
HTableDescriptor tableDesc = new HTableDescriptor("test");
tableDesc.setValue(HTableDescriptor.SPLIT_POLICY, ConstantSizeRegionSplitPolicy.class.getName());
tableDesc.addFamily(new HColumnDescriptor(Bytes.toBytes("cf1")));
admin.createTable(tableDesc);
在Hbase shell中对表进行配置
hbase> create ‘test‘, {METHOD => ‘table_att‘, CONFIG => {‘SPLIT_POLICY‘ => ‘org.apache.hadoop.hbase.regionserver.ConstantSizeRegionSplitPolicy‘}},{NAME => ‘cf1‘}
版权声明:本文为博主原创文章,未经博主允许不得转载。