1. rowkey是什么
可以理解为关系型数据库MySQL甲骨文的主键,用于标识唯一的行。
完全是由用户指定的一串不重复的字符串。
HBase中的数据永远是根据Rowkey的字典排序来排序的。
2. rowkey的作用
读写数据时通过RowKey找到对应的地区,例如需要查找一条数据肯定需要知道他的RowKey,写数据的时候也要根据RowKey来写。
MemStore中的数据按RowKey字典顺序排序,写数据的时候会先将数据放到MemStore也就是内存,内存中的数据是按照RowKey字典顺序排序的。
HFile中的数据按RowKey字典顺序排序,内存中的数据最后也会持久化到磁盘中,磁盘的数据HFile也是按RowKey字典顺序排序。
3. rowkey对查询的影响
例:RowKey由uid +电话+名字组成
1。可以很好的支持的场景
-
<李>
uid=111和电话=123和名称=abc
李> <李>uid=111和电话=123
李> <李>uid=111和电话=12 ?
李> <李>uid=111
<代码>这种场景下我们都指定了uid部分,也就是RowKey的第一部分,第一种查询的RowKey是完整的格式,所以查询效率是最好的,后边的三个虽然没有指定完整RowKey,但是查询的支持度也还不错。代码>李>
2。难支持的场景
-
<李>
=123电话和名称=abc
李> <李>电话=123 李> <李> abc
name=
<代码>这种场景下并没有指定RowKey的第一部分uid,只通过电话跟名字去做查询,也就是不指定先导部分,那么这种场景会导致HBase的查询的时候去进行全表扫描,降低了查询效率。代码>李>
4. rowkey对地区划分影响
HBase表的数据是按照RowKey来分散到不同的地区,不合理的RowKey设计会导致热点问题,热点问题是大量的客户端直接访问集群的一个或极少数个节点,而集群中的其他节点却处于相对空闲的状态,从而影响对HBase表的读写性能。
5. rowkey的设计技巧
1.盐(加盐)
<代码>盐的原理是将固定长度的随机数放在行键的起始处,具体就是给rowkey分配一个随机前缀以使得它和之前排序不同。分配的前缀种类数量应该和你想使数据分散到不同的地区的数量一致。如果你有一些热点rowkey反复出现在其他分布均匀的rwokey中,加盐是很有用的。代码>
例:假如你有下列rowkey,你表中每一个地区对应字母表中每一个字母。以“a”开头是同一个地区,“b”开头的是同一个地区。在表中,所有以“f”开头的都在同一个地区,它们的rowkey像下面这样:
<代码> foo0001 a-foo0001 foo0002===比;b-foo0002 foo0003 c-foo0003 foo0004 d-foo0004 代码>
假如你需要将上面这个地区分散到4个地区。你可以用4个不同的盐:“a”、“b”,“c”,“d”。在这个方案下,每一个字母前缀都会在不同的地区中。加盐之后,就像上边的例子。
所以,你可以向4个不同的地区写,理论上说,如果所有人都向同一个地区写的话,你将拥有之前4倍的吞吐量。
<代码>优缺点:由于前缀是随机生成的,因此想要按照字典顺序找到这些行,则需要做更多的工作,从这个角度上看,盐增加了写操作的吞吐量,却也增加了读操作的开销。代码>
2.哈希
哈希的原理是计算RowKey的哈希值,然后取散列的部分字符串和原来的RowKey进行拼接。这里说的散列包含MD5、sha1, sha256或sha512等算法,并不是仅限于Java的散列值计算。
例:比如我们有如下的RowKey:
<代码> foo0001 95 f18cfoo0001 foo0002===比;6 ccc20foo0002 foo0003 b61d00foo0003 foo0004 1 a7475foo0004 代码>
我们使用md5计算这些RowKey的哈希值,然后取前6位和原来的RowKey拼接得到新的RowKey,如上
<代码>优缺点:可以一定程度打散整个数据集,但是不利于扫描,比如我们使用md5算法,来计算Rowkey的md5值,然后截取前几位的字符串。 常见用法:subString (MD5(设备ID), 0, x) +设备ID,其中x一般取5或6。代码>
3.扭转(反转)
<代码>扭转的原理是反转一段固定长度或者全部的键。代码>
例:比如我们有以下URL,并作为RowKey:
<代码> flink.iteblog.com moc.golbeti.knilf www.iteblog.com===比;moc.golbeti.www carbondata.iteblog.com moc.golbeti.atadnobrac def.iteblog.com moc.golbeti.fedHBase Rowkey设计规范