- 拆分决定因素
Hbase中的表的region的拆分主要由以下的因素决定
Min (R^2 * “hbase.hregion.memstore.flush.size”, “hbase.hregion.max.filesize”)
其中R是该region中所包含的该表的region的数量,一般情况下如果memstore.flush.size 的值是128M,那么当开始新建一张表并开始写入数据时,当达到128M开始第一次拆分,之后依次是512MB, 1152MB, 2GB, 3.2GB, 4.6GB, 6.2GB时候开始进行拆分,当达到max.filesize的设定值时便会永远在storefile 达到max.filesize进行拆分(默认情况下这个值是10G,在0.90.x版本是256M,现在版本中的默认是是10G),需要特别注意的是filessize指的是store下的storefile的大小并不是整个region的大小,一个region可能包含很多个store,确切的说是该表有多少个family就有多少个store,当某个family下的storefile达到以上标准是就会拆分整个region而不管改region下的其他的store下的storefile是否已经达到触发条件。按照我的理解,当第一次拆分后所生成的两个新的region,而这两个region有可能会被分配给不同的region server所以当这个region server 进行第二次拆分的时候R的值有可能是1而不是2,这样一直到所有的region server的节点全部分配到一个region为此(这还需要进一步去验证,因为我至今还搞不清楚当一个region进行拆分式会不会把拆分后的两个region都assign给父region所在的region server,当然我这样的猜测的依据是当出现一个hot region的时候通过手工拆分region可以达到负载均衡的目的,既然是达到负载均衡那肯定是把拆分后的俩region分配到了不同的region sever否则负载均衡大约无从谈起)。
- 预拆分
region拆分的另一个问题是当一个新表刚开始建立的时候,默认是一个region这就意味着所有的客户端请求都要去请求这个region所在的region server,这样子其实限制了整个集群的能力,一直到数据足够大到能够触发拆分,并且拆分到的region能够均匀的分布到各个region server中去之后才能发挥整个集群的威力。按照上面的拆分约定,第一次拆分仅仅是store的数据达到128M,这并不算大,但是并不意味着可以等待这样的自动拆分,设想一种极端的情况,表建立之后就有1000个客户端同时请求写入数据,那么要等待自动拆分到足够region的数量才能够均衡这样的1000个客户端请求,那效率依然是十分低下的。解决的办法是在创建表的时候进行预拆分,就是在建表的时候先预先创建多个region这样子客户端请求的时候就可以分散到不同的region server去请求写入。
第一种对表进行预拆分的方法
$ hbase org.apache.hadoop.hbase.util.RegionSplitter test_table HexStringSplit -c 10 -f f1:f2:f3
表名:test_table
拆分的region的数量:10
family:f1,f2,f3
第二中预拆分的方法是,当知道rowkey的分布的时候可以指定每个预拆分的region的rowkey的开始值:
hbase(main):015:0> create 'test_table', 'f1', SPLITS=> ['a', 'b', 'c']
- 手动拆分
当出现hot region的时候,通常是因为rowkey设计不合理造成的,比如说是自增长的ID,会导致连续的行集中在同一个region中(默认是10G),如果这个region中连续的rowkey都是近一个月的数据,而客户端请求得最为频繁的也是当月的数据,那么就会造成所有请求当月数据的的客户端都连接到该region,导致阻塞,所以彻底解决办法是对rowkey进行良好的设计以让rowkey在集群中均匀分布,如果hot region已经产生,那么就需要手动的去拆分region以让拆分出来的两个region或者数个region分布到不同的region server中去
hbase(main):024:0> split 'b07d0034cbe72cb040ae9cf66300a10c', 'b'
- 拆分流程
- 合并