HBASE region简介
Region是HBase数据管理的基本单位,region有一点像关系型数据的分区。
region中存储这用户的真实数据,而为了管理这些数据,HBase使用了RegionSever来管理region。
Region的结构
一、为什么要预分区
默认情况下创建的表是只有1个Region的
在数据写入时,所有数据都会写入这个默认的Region
随着数据量的不断增加,此Region已经不能承受不断增长的数据量,会进行Split,分裂成2个Region。
在这个过程中,会产生两个问题:
1、数据往一个Region上写,会有写热点问题。
2、Region split会消耗宝贵的集群IO资源。
由此我们可以在建表的时候,创建多个空Region,并确定每个Region的起始和终止Rowkey,这样只要我们设计的Rowkey能均匀的命中各个Region。Region分裂的几率也会大大降低。
到HBase的界面中查看这个表的region信息
http://bigdata01:16010/
热点现象的产生
HBase 中的行是按照 Rowkey 的字典顺序排序的,这种设计优化了 scan 操作,可以将相关的行以及会被一起读取的行存取在临近位置,便于 scan。
然而糟糕的 Rowkey 设计是热点的源头。 热点发生在大量的 client 直接访问集群的一个或极少数个节点(访问可能是读,写或者其他操作)。
大量访问会使热点 region 所在的单个机器超出自身承受能力,引起性能下降甚至 region 不可用,这也会影响同一个 RegionServer 上的其他 region,由于主机无法服务其他 region 的请求,这样就造成数据热点现象。 (这一点其实和数据倾斜类似)
所以我们在向 HBase 中插入数据的时候,应优化 RowKey 的设计,使数据被写入集群的多个 region,而不是一个。尽量均衡地把记录分散到不同的 Region 中去,平衡每个 Region 的压力。
二、region拆分方式
(一)自动拆分
HBase是自动处理region拆分的:一旦它们达到了既定的阈值,region将被拆分成两个,之后它们可以接收新的数据并继续增长。
IncreasingToUpperBoundRegionSplitPolicy(0.94 版本后默认)
Math.min(tableRegionsCounts^3 * initialSize,defaultRegionMaxFileSize)
文件尺寸的上限增长
ableRegionCounts是表在所有 RegionServer 上所拥有的 Region 数量总和
initialSize 默认为memstore2倍
defaultRegionMaxFileSize region最大大小。默认10G
假设只有一个region,memstore是128M,10g
min(1 ^ 3 * 2 * 128, 10G) = 256M
也就是当达到256M时,就会拆分
同理2个region时,当每个region达到2G时会拆分
3个region时,当每个region达到6.75G时会拆分
4个region时,当每个region达到10G时会拆分
4个往上就都是10G
当 Region 个数达到 4 个的时候由于计算出来的上限已经达到了 16GB,已经大于 10GB 了,所以后面当 Region 数量再增加的时候文件大小上限已经不会增加了。在最新的版本里 IncreasingToUpperBoundRegionSplitPolicy 是默认的配置
(二)预拆分
手动指定拆分点
在建表的时候跟上 SPLITS 参数
第一种情况:
create ‘test_split2’,‘mycf2’,SPLITS=>[‘aaa’,‘bbb’,‘ccc’,‘ddd’,‘eee’]
第二种情况:
首先要明白数据的key是如何分布的,然后规划一下要分成多少region,每个region的startkey和endkey是多少,然后将规划的key写到一个文件中。比如,key的前几位字符串都是从0001~0010的数字,这样可以分成10个region,划分key的文件如下:
准备文件:region_split_info.txt
0001|
0002|
0003|
0004|
0005|
0006|
"|“是因为在ASCII码中,”|"的值是124,大于所有的数字和字母等符号,也可以用“~”(ASCII-126)
创建预分区表
create ‘split_table_test’,{NAME =>‘cf’}, {SPLITS_FILE => ‘region_split_info.txt’}
使用自定义算法
RegionSplitter工具提供了HBase,并使用SplitAlgorithm为您确定拆分点。作为参数,您可以给出算法,所需的区域数量和列族。它包括三个分割算法。
第二种 HexStringSplit 算法,它假定行键是十六进制字符串。
第二种 DecimalStringSplit 算法是假定行键是00000000到99999999范围内的十进制字符串。第三种 UniformSplit假设行键是随机字节数组。您可能需要开发自己的 SplitAlgorithm,使用提供的模型。
(三)强制拆分
除了预拆分和自动拆分以外,你还可以对运行了一段时间的Region 进行强制地手动拆分(forced splits)。方法是调用hbase shell的 split方法,比如:
上图是之前做的一个Region通过HBase命令行进行拆分
下面展示一些 内联代码片
。
split ‘split2,bb,1595513677802.c798b2717d6d7006bd67ad4e6197ed43’
split2——表名
bb——起始key
1595513677802——终止key
c798b2717d6d7006bd67ad4e6197ed43——终止key的id
现在可以根据这个id在bb和cc之间在强制拆分一个Region
HBase命令行输入命令:
split ‘c798b2717d6d7006bd67ad4e6197ed43’,‘c’
就可以发现bb和ccRegion之间又强制被拆分一个Region
PS:因为Region的排序是按照字典顺序排序的,所以在强制拆分的时候,要注意Region名的大小
split ‘tableName’
split ‘namespace:tableName’
split ‘regionName’ # format: ‘tableName,startKey,id’
split ‘tableName’, ‘splitKey’
split ‘regionName’, ‘splitKey’
三、推荐Region拆分的方案
(1)用预拆分导入初始数据。
(2)然后用自动拆分来让HBase来自动管理Region。
建议:不要关闭自动拆分
四、Hbase的Web界面简单介绍
表和快照信息
五、ROWKEY设计
RowKey 的设计原则
长度原则:
建议越短越好,不要超过 16 个字节,另外,我们目前使用的服务器操作系统都是 64 位系统,内存是按照 8B 对齐的,因此设计 RowKey 时一般做成 8B 的整数倍,如 16B 或者 24B,可以提高寻址效率。
唯一原则:
RowKey 用来唯一标识一行记录,必须在设计上保证 RowKey 的唯一性。
排序原则:
RowKey 是按照字典顺序排序存储的,要充分利用这个排序的特点,将经常读取的数据存储到一块,将最近可能会被访问的数据放到一块。
散列原则:
如果没有散列字段,那就可能会出现热点现象,这样在做数据检索的时候负载将会集中在个别 RegionServer 上,降低查询效率。
RowKey的优化
反转
把固定长度或者数字格式的 rowkey进行反转
适用场景:RowKey尾部的数据却呈现出了良好的随机性
加盐
RowKey的前面添加固定长度的随机数
适用场景:RowKey尾部的数据却呈现出了良好的随机性
哈希
hash常用的有MD5、sha1、sha256 或 sha512 等算法
适用场景:哈希和加盐的适用场景类似,但是由于加盐方法的前缀是随机数,用原rowkey查询时不方便,因此出现了哈希方法,由于哈希是使用各种常见的算法来计算出的前缀,因此哈希既可以使负载分散到整个集群,又可以轻松读取数据。
本文为简介详细内容可以参考以下大佬整理的内容
参考文档
链接: HBase 管理(Region自动拆分,预拆分,强制拆分,Region合并,HFile的合并)
链接: HBase RowKey详细设计