这篇文章给大家介绍HBase1.x中Region的拆分是怎样的,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。
第一部门:Region拆分的实现
client端向hbase写数据,首先从zookeeper中获取元数据存储所在的regionserver,查找对应的region,在region中寻找列族,先向memstore中写入数据,开始都会先写入memstore(默认128MB)中(如果开启了WAL日志,则先写入WAL日志),随着数据写入增加,触发溢写操作(flush),溢写到磁盘文件生成StoreFile。当存储文件堆积时,RegionServer会将它们压缩成更少、更大的文件。每次刷新或压缩完成后,该区域中存储的数据量将发生变化。RegionServer会根据配置的Region拆分策略,以确定是否提交拆分请求。
拆分策略配置在hbase-site.xml中,HBase的默认拆分策略:IncreasingToUpperBoundRegionSplitPolicy:
<property> <name>hbase.regionserver.region.split.policy</name> <value>org.apache.hadoop.hbase.regionserver.IncreasingToUpperBoundRegionSplitPolicy</value></property>
拆分Region是由Regionserver本地决定,但是会有很多参与者协调,Regionserver再进行拆分前后都会通知HMaster,更新.mea元数据表信息,并重排HDFS目录结构和数据文件;Regionserver会保留执行状态的日志,以便发生错误时进行任务回滚,下面是HBase官网Region拆分实现流程图,来自RegionServers或Master的操作显示为红色,而来自客户端的操作显示为绿色,如图所示:
RegionServer拆分第一步,RegionServer获取表上的共享读锁定,以防止在拆分过程中修改架构。然后它在zookeeper下的/hbase/region-in-transition/region-name创建一个znode,并将znode的状态设置为SPLITTING。
Master开始了解znode,因为它有一个 region-in-transition的观察器。
RegionServer在HDFS中的parent region目录下创建一个子目录.splits。
RegionServer关闭parent region并在其本地数据结构中将region标记为离线。拆分region现在处于离线状态。这时来自parent region的客户端请求将抛出NotServingRegionException。客户端将重试一些备份。关闭Region被刷新。
RegionServer在.splits目录下为child regionA和B创建region目录,并创建必要的数据结构。然后,它会拆分存储文件,因为它会在parent region中为每个存储文件创建两个引用文件。这些引用文件将指向parent region的文件。
RegionServer在HDFS中创建实际的region目录,并为每个child region移动引用文件。
RegionServer向.META.表发送一个Put请求,并将.META.表中的parent region设置为离线,添加有关子child region的信息。这里,.META.中的子region将不会有单独的条目。客户端将看到parent region在扫描.META.时被拆分。但直到他们出现在.META.其中才会知道这些child region。此外,如果Put到.META.成功后,parent region将会有效地拆分。如果RegionServer在此RPC成功之前失败,则Master和下一个Region Server打开该区域将清除有关region拆分的不干净状态。更新.META.之后,region分割将由Master进行前滚。
RegionServer并行打开child reigon A和B.
RegionServer将child reigon A和B添加到.META.,连同它承载区域的信息。拆分reigon 现在处于在线状态。在此之后,客户端可以发现新的reigon 并向他们发出请求。客户端在本地缓存.META.条目,但是当他们向RegionServer或者.META.发出请求时,他们的缓存将失效,他们将从.META.中了解新的reigon 。
RegionServer更新ZooKeeper中的znode /hbase/region-in-transition/region-name以表示状态SPLIT,以便主服务器可以了解它。必要时,平衡器可以自由地将子reigon 重新分配给其他RegionServer。拆分事务现在已完成。
拆分之后,.META.和HDFS仍将包含对parent region的引用。在child region中进行压缩重写数据文件时,这些引用将被删除。主服务器中的垃圾收集任务会定期检查child region是否仍然引用parent region的文件。否则,parent region将被删除。
第二部分:Region拆分方式
主要有三种拆分方式:预拆分、自动拆分、手动强制拆分;
1.预拆分,
就是在新建表时进行region拆分,根据数据分布特点,提前预分区可减少rowkey热点问题,另一方面减少region分裂导致短时不可用。
两种方法预分区:
方法一:
hbase org.apache.hadoop.hbase.util.RegionSplitter table_spilt_test1 HexStringSplit -c 10 -f info1:info2:info3
表名:table_spilt_test1
拆分的region的数量:10
列族:info1,info2,info3
方法二:
指定每个预拆分的region的rowkey的开始值
create 'test_table', 'table_spilt_test1 ', SPLITS=> ['1001', '2001', '3001']
2.自动拆分:
Region默认大小为10G,超过10G就自动进行拆分,Region大小通过下面面这个参数控制,生产环境如果预分区后,每个Region数据都比较大可改成20G 30G:
<property> <name>hbase.hregion.max.filesize</name> <value>10737418240</value> </property>
3.手动强制拆分:
可在hbase shell根据提示,对某个region进行强制拆分
Examples: split 'tableName' split 'namespace:tableName' split 'regionName' # format: 'tableName,startKey,id' split 'tableName', 'splitKey' split 'regionName', 'splitKey
第三部分:Region拆分触发条件
HBase表的拆分由以下公式决定:
Min (X^2 * "hbase.hregion.memstore.flush.size", "hbase.hregion.max.filesize")
说明:
1).X是该region中所包含的该表的region的数量;
2).hbase.hregion.memstore.flush.size默认值是128M;
3).hbase.hregion.max.filesize 默认值是10GB
新建一张表并开始写入数据时,当达到128M开始第一次拆分,之后依次是512MB, 1152MB, 2GB, 3.2GB, 4.6GB, 6.2GB时候开始进行拆分,当达到hbase.hregion.max.filesize的设定值时便会永远在storefile 达到hbase.hregion.max.filesize进行拆分。
需要特别注意的是filessize指的是store下的storefile的大小并不是整个region的大小,一个region可能包含很多个store,确切的说是该表有多少个family就有多少个store,当某个family下的storefile达到以上标准是就会拆分整个region而不管改region下的其他的store下的storefile是否已经达到触发条件。
关于HBase1.x中Region的拆分是怎样的就分享到这里了,希望以上内容可以对大家有一定的帮助,可以学到更多知识。如果觉得文章不错,可以把它分享出去让更多的人看到。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。