HBase的数据热点和Hbase常见避免热点问题的方法

只要使用过,听说过HBase的人,我想对HBase的数据热点想必也不会陌生。

数据热点是如何出现的,这得从HBase的存储结构说起,对于HBase详细的存储结构可以上网搜一下,这里就不补充了。

我们只需要知道,我们的HBase的表会被划分为1个或多个Region,被托管在RegionServer中。

HBase的数据热点和Hbase常见避免热点问题的方法

Region被托管在RegionServer中

由上图我们可以看出,Region有两个重要的属性:StartKey和EndKey。表示这个Region维护的rowkey的范围,当我们要读写数据时,如果rowkey落在某个start-end key范围内,那么就会定位到目标region并且读写到相关的数据。

默认情况下,当我们通过hbaseAdmin来创建一张表时,刚开始的时候只有一个Region,start-endkey无边界,也就是说无论来什么,本Region统统收,如下图。

HBase的数据热点和Hbase常见避免热点问题的方法

一个Region,无边界

所有的rowkey都写入到这个region里,然后数据越来越多,region的size越来越大时,大到一定的阀值,hbase就会将region一分为二,成为2个region,这个过程称为分裂(region-split)。

如果我们就这样默认建表,表里不断的put数据,一般情况我们的rowkey还是顺序增大的,这样,存在的缺点比较明显:我们总是向最大的startkey所在的region写数据,因为我们的rowkey总是会比之前的大,并且hbase的是按升序方式排序的。所以写操作总是被定位到无上界的那个region中,之前分裂出来的region不会被写数据,所以这样产生的结果是不利的。

如果在写比较频繁的场景下,数据增长太快,split的次数也会增多,由于split是比较耗费资源的,所以我们并不希望这种事情经常发生。

在集群中为了得到更好的并行性,让每个节点提供的请求都是均衡的,我们也不希望,region不要经常split,因为split会使server有一段时间的停顿,如何能做到呢?

rowkey的散列或预分区貌似就可以办的到。

预分区一开始就预建好了一部分region,这些region都维护着自己的start-end keys,我们将rowkey做一些处理,比如RowKey%i,写数据能均衡的命中这些预建的region,就能解决上面的那些缺点,大大提供性能。

而将rowkey散列化就是避免rowkey自增,这样也能解决上面所说的缺点。

Hbase常见避免热点问题的方法
加盐
一把rowkey前缀,决定了在哪一个分区。

HBase的数据热点和Hbase常见避免热点问题的方法

HBase的数据热点和Hbase常见避免热点问题的方法

降低热点问题,但是会造成读的时候,效率下降。

HBase的数据热点和Hbase常见避免热点问题的方法

HBase的数据热点和Hbase常见避免热点问题的方法

哈希
HBase的数据热点和Hbase常见避免热点问题的方法

反转
HBase的数据热点和Hbase常见避免热点问题的方法

举例:

HBase的数据热点和Hbase常见避免热点问题的方法

前缀都是一样,可能都会往一个region里面写数据时,就会出现热点问题。

返回来,把号码倒过来,就会是不同的数字,解决了热点问题。 

时间戳反转
HBase的数据热点和Hbase常见避免热点问题的方法

HBASE总结
1、尽量减少行和列的大小

HBase的数据热点和Hbase常见避免热点问题的方法

2、列簇尽可能越短越好,最好是一个字符

3、冗长的属性名虽然可读性好,但是更短的属性存储在HBase中会更好