ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

HBase 热点问题——rowkey散列和预分区设计

2022-01-26 17:07:12  阅读:205  来源: 互联网

标签:前缀 region xFF split rowkey HBase 散列 分区


预分区背景

HBase默认建表时有一个region,这个region的rowkey是没有边界的,即没有startkey和endkey,在数据写入时,所有数据都会写入这个默认的region,随着数据量的不断增加,此region已经不能承受不断增长的数据量,会进行split,分成2个region。

在此过程中,会产生两个问题:

  1. 数据往一个region上写,会有写热点问题。造成单机负载压力大,影响业务的正常读写。
  2. region split会消耗宝贵的集群I/O资源。

基于此我们可以控制在建表的时候,创建多个空region,并确定每个region的起始和终止rowky,这样只要我们的rowkey设计能均匀的命中各个region,就不会存在写热点问题。自然split的几率也会大大降低。当然随着数据量的不断增长,该split的还是要进行split。像这样预先创建hbase表分区的方式,称之为 预分区

热点发生在大量的client直接访问集群的一个或极少数个节点(访问可能是读,写或者其他操作)。大量访问会使热点region所在的单个机器超出自身承受能力,引起性能下降甚至region不可用,这也会影响同一个RegionServer上的其他region,由于主机无法服务其他region的请求,造成资源浪费。设计良好的数据访问模式以使集群被充分,均衡的利用。

数据倾斜:Hbase可以被划分为多个Region,但是默认创建时只有一个Region分布在集群的一个节点上,数据一开始时都集中在这个Region,也就是集中在这一个节点上,就算region存储达到临界值时被划分,数据也是存储在少数节点上。这就是数据倾斜

随机散列与预分区二者结合起来,是比较完美的。预分区一开始就预建好了一部分region,这些region都维护着自己的start-end keys,在配合上随机散列,写数据能均衡的命中这些预建的region,就能解决上面的那些缺点,大大提供性能。

1. 固定散列值

如果对rowkey加前缀盐处理,可以选择固定前缀预分区,分区规则如

  • a , b , c , d
  • 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9

这里所说的加盐不是 密码学中的加盐 ,而是在 rowkey 的前面增加随机数,具体就是给 rowkey 分配一个随机前缀以使得它和之前的 rowkey 的开头不同。分配的前缀种类数量应该 和你想使用数据分散到不同的 region 的数量一致。加盐之后的 rowkey 就会根据随机生成的 前缀分散到各个 region 上,以避免热点。

create 'user1',{NAME=>'f'},{NAME=>'d'},SPLITS=>['0|','1|','3|','4|','5|','6|','7|','8|','9|']

固定值散列,后面添加"|",因为|编码值最大

2. HexStringSplit(ASCII码预拆分策略)

Hbase 自带了两种 pre-split 的算法,分别是 HexStringSplit 和 UniformSplit 。HexStringSplit 适用于十六进制字符的 Rowkey(MD5)。UniformSplit 适用于随机字节组成的 Rowkey(Hash)。

如果我们的row key是 十六进制的字符串 作为前缀的,称之为HexStringSplit就比较适合用HexStringSplit,作为pre-split的算法。例如,我们使用HexHash(prefix)作为row key的前缀,其中Hexhash为最终得到十六进制字符串的hash算法,我们通常手动指定SPLITS来指定预分区,我们也可以用我们自己的split算法。

create 'test',{NAME=>'f',COMPRESSION=>'SNAPPY'},{NUMREGIONS => 30, SPLITALGO => 'HexStringSplit'}

3. UniformSplit(字节码预拆分策略)

只需要传入一个要拆分的Region的数量
与ASCII码预拆分不同的是,起始结束不是String而是 byte[]

  • 起始rowkey是 ArrayUtils.EMPTY_BYTE_ARRAY = new byte[0];
  • 结束rowkey是 new byte[]{xFF,xFF,xFF,xFF,xFF,xFF,xFF,xFF}

长度n等分,然后取每一段的起始和结束作为拆分点

防止热点的有效措施

哈希
 
哈希会使同一行永远用一个前缀加盐。哈希也可以使负载分散到整个集群,但是读却是 可以预测的。使用确定的哈希可以让客户端重构完整的 rowkey,可以使用 get 操作准确获取 某一个行数据

HBase 写入流程

  • 第1步:Client获取数据写入的Region所在的RegionServer
  • 第2步:请求写Hlog
  • 第3步:请求写MemStore

只有当写Hlog和写MemStore都成功了才算请求写入完成。MemStore后续会逐渐刷到HDFS中。Hlog存储在HDFS,当RegionServer出现异常,需要使用Hlog来恢复数据。

标签:前缀,region,xFF,split,rowkey,HBase,散列,分区
来源: https://blog.csdn.net/qq_26857259/article/details/122702800

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有