hbase rowKey设计原则

不错的文章:

https://blog.csdn.net/zhanglh046/article/details/78517928

https://blog.csdn.net/wangshuminjava/article/details/80575864#commentBox

 

1、散列性(rowkey尽量均匀的分布到多个region,并且有可能的话某些条件一样的数据都集中在同一个region,方便范围查询)

2、唯一性(rowKey唯一)

3、有序性

4、长度

 

优化方式:

1、通过hash、反转、随机数、Long.MAX_VALUE-timestamp等几种方式可以保证散列性。

(1)不过hash-------散列性

哈希会使得同一行永远使用同一个加盐前缀,也可以使得负载分散到整个集群,但是是可以预测的,因为相同hash值的数据(相同hash的数据不超过region本身数据限制)会在同一个region中。使用确定的哈希可以让客户端重构完成row key。

对于get查询友好(因为hash值在客户端可以通过条件计算出来,然后自然可以拼装出rowkey)。

对scan查询不友好,无法有效利用startRow和stopRow。

(2)反转 ----散列性

使用场景:类似于手机号、时间戳这类的,前面部分变化不大,后面部分经常变化。。反转之后就会变成前面部分经常变化,然后就相当于随机分散到不同的region了。但是牺牲了row key的排序,对scan不好。

对于get查询友好,在客户端就可以计算出反转的值。

对scan查询不友好,无法有效利用startRow和stopRow。

(3)随机

对于写数据来说支持很好,因为随机范围如果和region数量一样,那么每条数据都会被随机写到不同的region,这样写数据的压力就极大分散了。

对于读数据:如果随机范围比较小,那么查询时可以把一个scan查询分N个scan,每个scan设置startRow和endRow时的前缀可以固定知道是随机范围中的值。然后一个scan分为N个scan并行查询,虽然会增加服务器压力,但scan查询速度会很快。并且,对于get查询也挺友好的,也是把一个get变为多个get,每个get的rowKey前缀对应随机数范围中的一个值。总的来说,查询速度变快,但查询压力变大。

 

(4)Long.MAX_VALUE-timestamp是利用了hbase的rowkey排序性,把新数据放在最前面,查询时提高命中率

一个常见的问题是快速获取数据的最近版本,我们可以将时间戳反转作为row key一部分,可以解决这个问题,可以将Long.MAX_VALUE-Timestamp追加到到row key末尾,比如[key][reverse_timestamp]。

表中[key]的最新值可以通过scan[key]获取[key]的第一条记录,因为HBase中row key是按照字典排序的,最新的[key]在任何旧的key的前面,所以第一条记录就是最新的

这个技巧可以替代使用多版本数据,对版本数据会很长时间保存数据的版本,同时这个技巧用一个scan操作就可以获得所有数据。

如果需要查询某段时间的操作记录,startRow是[key][Long.Max_Value - 起始时间],stopRow是[key][Long.Max_Value - 结束时间]。。也就是说,使用Long.MAX_VALUE-timestamp可以包含时间范围搜索替代hbase多版本数据两种功能,因为hbase本身虽然也是利用时间戳做多版本,但是如果无法控制查询某个时间范围内的所有版本数据,而只能说是查询出最近的指定几种版本(而且保存多少版本由表属性设置了),所以如果有查询某个时间范围内的所有版本数据的需求,那么就可以用这种方式代替。

(5)避免单调递增或递减row key(时间或者ID连续系列)

如果row key是那种序列化的id(1000,1001,1002诸如此类)或者时间戳(20170101,20170102)这种格式。它会导致在某一个时间段内,所有的数据全部写入到了同一个region

(6)、预分区:

首先,想好要分多少个region

假设要300个分区:

则分区键可以如下:

竖线也是分区键的一部分。。。因为该字符的字典序比其他大多字符都大。。也不一定要用竖线。

 

然后rowkey前四位是:

<1>前三位是根据rowkey的其他组成部分根据自定义算法计算出来的。。。该算法需既要保证散列性,也要保证一定的集中性

该算法是一个函数,由:

根据输入数据的hash值对该表的分区数求余。。。这样就可以保证散列性。并且根据一样的输入数据,都可以保证进入同一个region。

如果还要一定的集中性,那么输入数据则应该是需要组合的条件组成。。

比如电话详情,每条记录有以下字段:

手机号    年月日      通话时间

如果要保证同一个手机号同一个月的数据都在同一个region,而其他月份的数据则可以分散到其他region。。

那么计算hash值的输入数据每条记录都传入是由手机号+年月,然后由此得到的hash值再对region数求余,

那么,同一手机号在同一个月份的数据都肯定是在同一个region了。这就保证了集中性

 

总结:每条记录的rowkey主要由三部分组成:分区键+排序字段+其他可以让rowkey保证唯一性的字段。

(1)其中分区键用来表明该记录所处的分区。在存入hbase时。根据<1>中的算法,输入指定的几个字段用于计算该记录所属的分区键。

(2)想要在同一个region中让相同条件的数据集中在一块,可以利用hbase  rowkey自动排序特性。。分区键固定了,那么在后面加上排序的数据,hbase自然会让这些数据在同一个region中按指定字段的字典序排列了。。

(3)最后加上能保证rowkey唯一性的数据。。。

以上三部分,组成的rowkey

 

 

参考这段视频:https://www.bilibili.com/video/av65548392/?p=50

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值