但凡使用到HBase,数据量绝对不会少,这时候就需要考虑到查询的效率问题,以及可能出现的数据倾斜问题(热点问题)。我们可以同过对rowkey进行设计,规划一个合理的预分区,让数据散列的分布在各个分区上。
因此:rowkey设计时就要考虑到一个预分区的问题;同样,预分区也不可背离开rowkey而随意设置
- 预分区的个数大体上取决于两个方面:
- 集群规模大小;(一般一个节点上三个分区)
- 数据量的大小;(主要是估算以后的数据)
- RowKey设计原则:
- 散列性(重点)
- 唯一性(rowkey唯一)
- 长度原则(生产环境中一般70-100位)
散列性:
- 1. 生成随机数、hash值、散列值
- 2. 字符串反转
- 3. 字符串拼接
由此可见,避免热点的关键操作:
1.预分区 2.rowkey设计
-
1.预分区
在创建表的时候,配置一些策略,让一张表有多个region,分布在不同的regionserver上;
HBase自身会进行split,默认一个region,当他过大超过阈值(默认10G),会切分为两个Region,分布到新的regionserver上,父region下线。
-
2.rowkey设计
- 反转:例如时间戳,手机号。(缺点:将原表数据打乱分布在不同region上,进行全表扫描时,会从多个甚至所有region来获取数据)
- 加盐:在rowkey前面增加随机数。(缺点:无法指定rowkey进行查询,因为你不知道rowkey前面增加的随机数是什么)
- Hash:根据rowkey中的某个部分或全部取hash,这样即便之后我们需要指定rowkey查询,也可以先进性hash得出新的rowkey来查找。(但也会造成全表扫描时,会从多个甚至所有region来获取数据)
综上:以上的rowkey设计原则,都是为了将数据离散、均匀地分布在集群中的每个regionserver上,对rowkey进行打散,势必会造成原表中的数据在存储时不再有序,导致scan全表扫描性能下降。
所以我们通常会添加二级索引进来,弥补以上设计原则带来的不便。