分享

HBase避免写热点发生rowkey设计的疑惑

http://www.aboutyun.com/forum.php?mod=viewthread&tid=8909&extra=page%3D1&page=1
为了避免写数据热点的发生,这个帖子分享了如何根据rowkey来进行预分区,进而避免写热点的发生。

其中我有一些疑惑,看到网友也有类似的疑惑。所以想贴出来,让大神给指点一下。

对于hash方法进行预分区设计的时候,帖子中有如下的说法:
假设rowKey原本是自增长的long型,可以将rowkey转为hash再转为bytes,加上本身id 转为bytes,组成rowkey,这样就生成随便的rowkey
rowkey最后的结构为:(rowkey->转换为hash->再转换为byte) + (rowkey->转换为bytes)

疑惑1. 设计好预先分区以后,我们在向表中进行put数据的时候,这个rowkey是也需要按照预分区的时候的逻辑,进行转换才能得到一个新的值,而这个新的值就可以确定这个rowkey应该put到哪个region上去。我的理解没错吧?

如果是这样,那么现在假如说我的rowkey计划是用自增长的序列,那么我现在要put一个rowkey为13的行,那么这个rowkey结果hash转换,得到的一个新的值,应该不是13了吧?那么此时的rowkey会是一个byte数组吧:应该是:(13->转换为hash->再转换为byte) + (13->转换为bytes),这样一个数据组成的byte数组,这个数组可以将数据均匀的分布在所有的region上吗?假设现在再来一个14的rowkey,经过上面的转换,我感觉它会落到和13相同的region上?如果是这样,那么挨着的数据还是会放到同一个region上呀。

疑惑2:如果最后rowkey在Hbase表中是以byte数组的方式存放的,那么在HBase数据库中rowkey的值我们是不能直接看出来是什么了?那./hbase shell命令行中是不是就不能查询了?只能通过程序来将要查询吗?
假如是要查询rowkey为13的数据,那么我需要将13再通过上面的转换规则转换一次,得到一个byte数组?然后在用这个刚转换的byte数组作为rowkey去get数据,是这样吗?
还是说在HBase表中,rowkey的值,还是以13进行存储。我们可以通过/hbase shell 命令行直接根据rowkey等于13,可以get到对应的数据。只不过在判断这个13的rowkey该放到那个region上的时候,使用了上面的一系列的转换,让这个13的rowkey可以随机的分配到某一个region上。





已有(12)人评论

跳转到指定楼层
bioger_hit 发表于 2018-4-27 19:27:34
疑惑1. 设计好预先分区以后,我们在向表中进行put数据的时候,这个rowkey是也需要按照预分区的时候的逻辑,进行转换才能得到一个新的值,而这个新的值就可以确定这个rowkey应该put到哪个region上去。我的理解没错吧?
这个理解是没有错的

如果是这样,那么现在假如说我的rowkey计划是用自增长的序列,那么我现在要put一个rowkey为13的行,那么这个rowkey结果hash转换,得到的一个新的值,应该不是13了吧?那么此时的rowkey会是一个byte数组吧:应该是:(13->转换为hash->再转换为byte) + (13->转换为bytes),这样一个数据组成的byte数组,这个数组可以将数据均匀的分布在所有的region上吗?假设现在再来一个14的rowkey,经过上面的转换,我感觉它会落到和13相同的region上?如果是这样,那么挨着的数据还是会放到同一个region上呀。
这里楼主忽略了,哈希,看下面解释
hash就是rowkey前面由一串随机字符串组成,随机字符串生成方式可以由SHA或者MD5等方式生成,只要region所管理的start-end keys范围比较随机,那么就可以解决写热点问题。

比如13,我这里随机给他给他一个字符串.这里只是举例:具体有hbase自己的机制。
x1+13,经过哈希处理后x113
a1+14, 经过哈希处理后a114
由于hbase是按照顺序排的,那么a和x应该不是紧挨的。咱们在举数字
11+13,经过哈希处理后1113
23+14,经过哈希处理后2314
这样他们肯定不紧挨着了,这就是哈希的作用。




回复

使用道具 举报

bioger_hit 发表于 2018-4-27 19:32:21
本帖最后由 bioger_hit 于 2018-4-27 19:34 编辑

疑惑2:如果最后rowkey在Hbase表中是以byte数组的方式存放的,那么在HBase数据库中rowkey的值我们是不能直接看出来是什么了?那./hbase shell命令行中是不是就不能查询了?只能通过程序来将要查询吗?
假如是要查询rowkey为13的数据,那么我需要将13再通过上面的转换规则转换一次,得到一个byte数组?然后在用这个刚转换的byte数组作为rowkey去get数据,是这样吗?
还是说在HBase表中,rowkey的值,还是以13进行存储。我们可以通过/hbase shell 命令行直接根据rowkey等于13,可以get到对应的数据。只不过在判断这个13的rowkey该放到那个region上的时候,使用了上面的一系列的转换,让这个13的rowkey可以随机的分配到某一个region上。

这个如果前面加盐(salt)处理了,如果直接查询,那就查不出来了,不会出结果。那么该怎么办?
这时候,我们可以将前面的盐也就是随机数,通过RowFilter,将随机数过滤掉。如同我们Java中的contain,也就是包含13
推荐参考
hbase RowFilter如何根据rowkey查询以及实例实现代码
http://www.aboutyun.com/forum.php?mod=viewthread&tid=8895



点评

你的意思是:在HBase表中,rowkey的值就是以byte数组存储的。我们是没有办法直接使用hbase shell命令行查询的。需要通过代码,结合一下API,通过模糊匹配的方式去查询我们的想要的结果,我理解的对吗?  发表于 2018-4-27 21:03
回复

使用道具 举报

javaanddonet 发表于 2018-4-27 20:53:25
bioger_hit 发表于 2018-4-27 19:27
疑惑1. 设计好预先分区以后,我们在向表中进行put数据的时候,这个rowkey是也需要按照预分区的时候的逻辑, ...

看了你的举例,豁然开朗。多谢指教~
回复

使用道具 举报

javaanddonet 发表于 2018-4-27 21:08:57

你的意思是:在HBase表中,rowkey的值就是以byte数组存储的。我们是没有办法直接使用hbase shell命令行查询的。需要通过代码,结合一下API,通过模糊匹配的方式去查询我们的想要的结果,我理解的对吗?

疑问:通过这种过滤器,查询效率和不通过过滤器,效率一样吗?感觉通过过滤器会慢。
比如在HBase中rowkey就是以13这样一个数字存储的,我get,根据rowkey=13就能直接拿到了。
但是在这个13前面加上一些东西,比如说:x3942ee13 是经过hash换换后的rowkey,那么在hbase中存储的假如就是这个值,这样我查询的时候,需要使用过滤器,然后才能查询到13的这个记录。感觉会慢。
但是考虑到可以避免数据存储的时候倾斜和写热点的问题。这样的方式也是可以接受的。
回复

使用道具 举报

bioger_hit 发表于 2018-4-28 09:59:35
javaanddonet 发表于 2018-4-27 21:08
你的意思是:在HBase表中,rowkey的值就是以byte数组存储的。我们是没有办法直接使用hbase shell命令行查 ...

在HBase表中,rowkey的值就是以byte数组存储的。我们是没有办法直接使用hbase shell命令行查询的。需要通过代码,结合一下API,通过模糊匹配的方式去查询我们的想要的结果,我理解的对吗?
shell是可以查询的,api也可以,这两种方式都是可以的

疑问:通过这种过滤器,查询效率和不通过过滤器,效率一样吗?感觉通过过滤器会慢。
比如在HBase中rowkey就是以13这样一个数字存储的,我get,根据rowkey=13就能直接拿到了。
但是在这个13前面加上一些东西,比如说:x3942ee13 是经过hash换换后的rowkey,那么在hbase中存储的假如就是这个值,这样我查询的时候,需要使用过滤器,然后才能查询到13的这个记录。感觉会慢。
但是考虑到可以避免数据存储的时候倾斜和写热点的问题。这样的方式也是可以接受的。
效率会受一些影响,但是影响不大。这就涉及到该如何涉及rowkey设计,推荐参考这个
关于HBASE的rowkey设计

http://www.aboutyun.com/forum.php?mod=viewthread&tid=24420

回复

使用道具 举报

javaanddonet 发表于 2018-4-28 10:46:36
bioger_hit 发表于 2018-4-28 09:59
在HBase表中,rowkey的值就是以byte数组存储的。我们是没有办法直接使用hbase shell命令行查询的。需要通 ...

在HBase表中,rowkey的值就是以byte数组存储的。我们是没有办法直接使用hbase shell命令行查询的。需要通过代码,结合一下API,通过模糊匹配的方式去查询我们的想要的结果,我理解的对吗?
shell是可以查询的,api也可以,这两种方式都是可以的


rowkey,在表中不是以byte数组存储的吗?怎么通过shell命令行直接查询某一条记录?能详细说一下吗?多谢了。
回复

使用道具 举报

bioger_hit 发表于 2018-4-28 10:52:12
javaanddonet 发表于 2018-4-28 10:46
在HBase表中,rowkey的值就是以byte数组存储的。我们是没有办法直接使用hbase shell命令行查询的。需要通 ...

通过命令其实也是编程,类似shell编程。
api,只不过是在具体语言中调用。
这二者其实都是一样的。楼主感兴趣,可以看下hbase的启动命令等

回复

使用道具 举报

javaanddonet 发表于 2018-4-28 10:58:34
bioger_hit 发表于 2018-4-28 10:52
通过命令其实也是编程,类似shell编程。
api,只不过是在具体语言中调用。
这二者其实都是一样的。楼主 ...

我明白你的意思了,在shell命令行中,也是通过类似于RowFilter的东西来查询。总之就是要将rowkey还原成我们真正要的那个数值,把我们之前添加的东西都给去掉,就是你说的去salt,是吧?假如我就scan前10行数据,在shell命令行中显示的结果,我们并不能直接看到前10行的rowkey到底是什么,结果阅读性差了许多。是这样吧?

回复

使用道具 举报

bioger_hit 发表于 2018-4-28 11:30:46
javaanddonet 发表于 2018-4-28 10:58
我明白你的意思了,在shell命令行中,也是通过类似于RowFilter的东西来查询。总之就是要将rowkey还原成我 ...

rowkey你自己可以分别的,比如下面:
a0120180428
b0220180428
c0320180428
d0420180428
a,b,c,d是我们加的salt
01,02,03,04是我们的用户id
20180428是日期
回复

使用道具 举报

12下一页
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

关闭

推荐上一条 /2 下一条