检索 habse 的记录首先要通过 row key 来定位数据行 , 当大量的 client 访问 hbase 集群的一个或少数几个节点,
造成少数 region server 的读 / 写请求过多、负载过大,而其他 region server 负载却很小,就造成了 “ 热点 ” 现象 .
大量访问会使热点 region 所在的单个主机负载过大,引起性能下降甚至 region 不可用。
常见的避免热点的方法
( 1 )加盐
这里所说的加盐不是密码学中的加盐,而是在 rowkey 的前面增加随机数,具体就是给 rowkey 分配一个随机前缀以使得它和之前的
rowkey 的开头不同。给多少个前缀?这个数量应该和我们想要分散数据到不同的 region 的数量一致(类似 hive 里面的分桶)。
加盐之后的 rowkey 就会根据随机生成的前缀分散到各个 region 上,以避免热点。
( 2 )哈希
哈希会使同一行永远用一个前缀加盐。哈希也可以使负载分散到整个集群,但是读却是可以预测的。使用确定的哈希可以让客户端
重构完整的 rowkey ,可以使用 get 操作准确获取某一个行数据。
( 3 )反转
第三种防止热点的方法是反转固定长度或者数字格式的 rowkey 。这样可以使得 rowkey 中经常改变的部分(最没有意义的部分)放在
前面。这样可以有效的随机 rowkey ,但是牺牲了 rowkey 的有序性。
反转 rowkey 的例子:以手机号为 rowkey ,可以将手机号反转后的字符串作为 rowkey ,从而避免诸如 139 、 158 之类的固定号码开头导
致的热点问题。
( 4 )时间戳反转
一个常见的数据处理问题是快速获取数据的最近版本,使用反转的时间戳作为 rowkey 的一部分对这个问题十分有用,可以用
Long.Max_Value - timestamp 追加到 key 的末尾,例如 key ,[key] 的最新值可以通过 scan [key] 获得
[key] 的第一条记录,因为 HBase 中 rowkey 是有序的,第一条记录是最后录入的数据。
( 5 )尽量减少行和列的大小
在 HBase 中, value 永远和它的 key 一起传输的。当具体的值在系统间传输时,它的 rowkey ,列名,时间戳也会一起传输。
如果你的 rowkey 和列名很大, HBase storefiles 中的索引(有助于随机访问)会占据 HBase 分配的大量内存,因为具体
的值和它的 key 很大。可以增加 block 大小使得 storefiles 索引再更大的时间间隔增加,或者修改表的模式以减小 rowkey
和列名的大小。压缩也有助于更大的索引。
( 6 )其他办法
列族名的长度尽可能小,最好是只有一个字符。冗长的属性名虽然可读性好,但是更短的属性名存储在 HBase 中会更好。也
可以在建表时预估数据规模,预留 region 数量,例如 create 'myspace:mytable’, SPLITS => [01,02,03,,...99]