HBase ROWKEY设计原则
1 HBase官方的设计原则
1.1 避免使用递增行键/时序数据
如果ROWKEY设计的都是按照顺序递增(例如:时间戳),这样会有很多的数据写入时,负载都在一台机器上。我们尽量应当将写入大压力均衡到各个RegionServer
1.2 避免ROWKEY和列的长度过大
-
在HBase中,要访问一个Cell(单元格),需要有ROWKEY、列蔟、列名,如果ROWKEY、列名太大,就会占用较大内存空间。所以ROWKEY和列的长度应该尽量短小
-
ROWKEY的最大长度是64KB,建议越短越好
1.3 使用long等类型比String类型更省空间
long类型为8个字节,8个字节可以保存非常大的无符号整数,例如:18446744073709551615。如果是字符串,是按照一个字节一个字符方式保存,需要快3倍的字节数存储。
1.4 ROWKEY唯一性
-
设计ROWKEY时,必须保证RowKey的唯一性
-
由于在HBase中数据存储是Key-Value形式,若向HBase中同一张表插入相同RowKey的数据,则原先存在的数据会被新的数据覆盖。
2 避免数据热点
-
热点是指大量的客户端(client)直接访问集群的一个或者几个节点(可能是读、也可能是写)
-
大量地访问量可能会使得某个服务器节点超出承受能力,导致整个RegionServer的性能下降,其他的Region也会受影响
2.1 预分区
-
默认情况,一个HBase的表只有一个Region,被托管在一个RegionServer中
-
每个Region有两个重要的属性:Start Key、End Key,表示这个Region维护的ROWKEY范围
-
如果只有一个Region,那么Start Key、End Key都是空的,没有边界。所有的数据都会放在这个Region中,但当数据越来越大时,会将Region分裂,取一个Mid Key来分裂成两个Region
-
预分区个数 = 节点的倍数。默认Region的大小为10G,假设我们预估1年下来的大小为10T,则10000G / 10G = 1000个Region,所以,我们可以预设为1000个Region,这样,1000个Region将均衡地分布在各个节点上
2.2 ROWKEY避免热点设计
- 反转策略
如果设计出的ROWKEY在数据分布上不均匀,但ROWKEY尾部的数据却呈现出了良好的随机性,可以考虑将ROWKEY的翻转,或者直接将尾部的bytes提前到ROWKEY的开头。
反转策略可以使ROWKEY随机分布,但是牺牲了ROWKEY的有序性
缺点:利于Get操作,但不利于Scan操作,因为数据在原ROWKEY上的自然顺序已经被打乱
- 加盐策略
Salting(加盐)的原理是在原ROWKEY的前面添加固定长度的随机数,也就是给ROWKEY分配一个随机前缀使它和之间的ROWKEY的开头不同
随机数能保障数据在所有Regions间的负载均衡
缺点:因为添加的是随机数,基于原ROWKEY查询时无法知道随机数是什么,那样在查询的时候就需要去各个可能的Regions中查找,加盐对比读取是无力的
- 哈希策略
基于 ROWKEY的完整或部分数据进行 Hash,而后将Hashing后的值完整替换或部分替换原ROWKEY的前缀部分
这里说的 hash 包含 MD5、sha1、sha256 或 sha512 等算法
缺点:Hashing 也不利于 Scan,因为打乱了原RowKey的自然顺序