本篇文章主要分享Apache HBase如何通过regions实现负载均衡以及如何管理region拆分。
HBase以表的形式存储多行数据。表被划分为”regions“。Regions分布在集群的不同节点上,通过RegionServer进程被客户端调用。一个region由一组连接的Key组成,从一个start key开始,以end key结尾。Region之间不会overlap,这意味着一个固定的row key在某一个时刻只属于一个固定的region。一个region在某一个固定的时刻只会属于一个Region Server,这保证了HBase对于单个row的强一致性。与-ROOT-和.META.一起,表上的regions形成一个3级B-Tree结构,以便高效地定位表中的一行数据。
Region由多个Stores组成,一个store对应一个列族(Column Family)。一个store由1个mestore及0个或多个store files组成。每个列族的数据存储和获取都是相互独立的。
表由多个regions组成,这些regions分布在多个Region Server上面。因此,regions是一种把读写请求分布到不同的Region Server的物理机制。当表被创建时,HBase默认只会分配一个region。这意味着,初始状态时所有的请求都会在一个Region Sever上,而无论当前有多少个Region Server。
预拆分(Pre-splitting)
HBase提供一个预拆分机制,可以在创建表的时候通过指定拆分点把表拆分为多个regions,详情请参考另外一篇博客:http://blog.csdn.net/post_yuan/article/details/53541094
自动拆分(Auto splitting)
不管是否使用预拆分,一旦region达到一个指定的上限,它会自动拆分为2个regions。如果使用HBase 0.94版本,可以通过配置决定HBase什么时候拆分region,以及如何通过RegionSplitPolicy API计算拆分点。拆分机制包括多种,如 ConstantSizeRegionSplitPolicy, IncreasingToUpperBoundRegionSplitPolicy, 以及KeyPrefixRegionSplitPolicy。
ConstantSizeRegionSplitPolicy是在0.94版本以前默认的而且是唯一的拆分策略。当store的size达到配置的”hbase.hregion.max.filesize”(默认值为10G)时触发拆分操作。这个拆分策略在当你完成预拆分步骤并且希望获得相对低的region个数时候是十分理想的方案。
在0.94版本中,默认的拆分策略是IncreasingToUpperBoundRegionSplitPolicy。这种策略使用的最大store file size依据 Min(R^2 * “hbase.hregion.memstore.flush.size”, “hbase.hregion.max.filesize”),R代表同一台Region Server节点上的region的个数。比如,在默认memstore flush size为128MB且默认的max store size为10G时,第一个region在128MB时拆分,随着region个数的增加,将会使用512MB,1152MB,2GB,3.2GB,4.6GB,6.2GB等作为拆分点。在达到9个region之后,拆分的size会超过”hbase.hregion.max.filesize“,之后便都使用10GB作为拆分的size。
KeyPrefixRegionSplitPolicy是HBase一个新奇物。你可以配置row keys的前缀的长度来进行分组,这种策略确保regions不会在一组有相同前缀行的中间拆分。如果对keys设置了前缀,可以使用这个拆分策略保证有相同rowkey前缀的行落在一个region中。这个分组的方法有时候也称为”Entity Groups”或”Row Groups”。
可以通过配置”hbase.regionserver.region.split.polity”来配置默认拆分策略,或者直接配置在表的定义里面。
如果正在做pre-splitting,希望手动管理region拆分,也可以禁用region拆分,通过设置”hbase.region.max.filesize“为一个很高的值并且把拆分策略设为ConstantSizeRegionSplitPolicy。但需要设置一个安全的阈值如100GB,这样regions增长不会超过Region Server的能力。可以考虑禁用自动拆分并依赖于初始region的设置(来源于预分区),比如,当使用统一的对key进行哈希计算时,可以确保读/写负载以及数据存储
分散到每个region中。
强制拆分(Force splits)
HBase允许从客户端强制拆分一个在线的表。比如,HBase shell可以用来拆分一个表的所有regions,或者拆分一个region,如下
hbase(main):024:0> split 'b07d0034cbe72cb040ae9cf66300a10c', 'b'
0 row(s) in 0.1620 seconds
通过监控HBase的负载,如果发现某些regions负载不均衡,可以考虑手动拆分这些regions来均衡负载从而提升性能。另外一个需要强制拆分的原因是当发现初始的预拆分不正确的时候而且关闭了自动拆分。