Hbase rowkey 热点问题

来源:互联网 发布:优衣库淘宝假货 编辑:程序博客网 时间:2024/06/05 16:53

最近通过映射查询hbase的数据、非常慢、造成热点原因是rowkey设计不合理。造成数据倾斜都存在同一个reginserver上。所有的请求都跑到同一个reginserver上。


    当处理由连续事件得到的数据时,即时间上连续的数据。这些数据可能来自于某个传感器网络、证券交易或者一个监控系统。它们显著的特点就是rowkey中含有事件发生时间。带来的一个问题便是HBase对于row的不均衡分布,它们被存储在一个唯一的rowkey区间中,被称为region,区间的范围被称为Start Key和End Key。
对于单调递增的时间类型数据,很容易被散列到同一个Region中,这样它们会被存储在同一个服务器上,从而所有的访问和更新操作都会集中到这一台服务器上,从而在集群中形成一个hot spot,从而不能将集群的整体性能发挥出来。
要解决这个问题是非常容易的,只需要将所有的数据散列到全部的Region上即可。这是可以做到的,比如,在rowkey前面加上一个非线程序列,常常有如下选择:
Hash散列

您可以使用一个Hash前缀来保证所有的行被分发到多个Region服务器上。例如:
byte prefix =(byte) (Long.hashCode(timestamp) % );
byte[] rowkey =Bytes.add(Bytes.toBytes(prefix), Bytes.toBytes(timestamp);

这个公式可以产生足够的数字,将数据散列到所有的Region服务器上。当然,公式里假定了Region服务器的数目。如果您打算后期扩容您的集群,那么您可以把它先设置为集群的整数倍。生成的rowkey类似下面:

0myrowkey-1,1myrowkey-2, 2myrowkey-3, 0myrowkey-4, 1myrowkey-5, 2myrowkey-6, …

当他们将按如下顺序被发送到各个Region服务器上去:0myrowkey-1,0myrowkey-4,1myrowkey-2,1myrowkey-5 …

换句话说,对于0myrowkey-1和0myrowkey-4的更新操作会被发送到同一个region服务器上去(假定它们没有被散列到两个region上去),1myrowkey-2和1myrowkey-5会被发送到同一台服务器上。
这种方式的缺点是,rowkey的范围必须通过代码来控制,同时对数据的访问,可能要访问多台region服务器。当然,可以通过多个线程同时访问,来实现并行化的数据读取。这种类似于只有map的MapReduce任务,可以大大增加IO的性能。
另外一种是数据外部进来的需要进行转换生成一批的对应的rowkey就可以用到前面的两个rowkey的设计理念
0 0