HBase 数据定位
HBase 是三维有序存储的,通过 RowKey(行键)、Column Key(列族和限定符)和 Timestamp(时间戳)这三个维度可以对 HBase 中的数据进行快速定位。
RowKey 长度原则
RowKey 是一个二进制码流,可以是任意字符串,最大长度 64KB,实际应用中一般为 10-100 字节,以 byte[] 形式保存,一般设计成定长。
建议越短越好,不要超过 16 个字节,原因如下:
- 数据的持久化文件 HFile 中是按照 KeyValue 存储的,如果 RowKey 过长,比如超过 100 字节,1000 万行数据,光 RowKey 就要占用 100*1000 万=10 亿个字节,将近 1GB 数据,这样会极大影响 HFile 的存储效率;
- MemStore 将缓存部分数据到内存,如果 RowKey 字段过长,可能会导致 MemStore 空间不足,从而影响性能;
- RowKey 长度越短,索引文件占用的空间也越小,可以提高读写效率。
防止热点
- 加盐:在 RowKey 的前面增加随机数,具体就是给 RowKey 分配一个随机前缀以使得它和之前的 RowKey 的开头不同。分配的前缀种类数量应该和你想使用数据分散到不同的 Region 的数量一致。
- 哈希:哈希会使同一行永远用一个前缀加盐。哈希也可以使负载分散到整个集群,但是读却是可以预测的。使用确定的哈希可以让客户端重构完整的 RowKey,可以使用 Get 操作准确获取某一个行数据。
- 反转:第三种防止热点的方法是反转固定长度或者数字格式的 RowKey。这样可以使得 RowKey 中经常改变的部分(最没有意义的部分)放在前面。这样可以有效地随机 RowKey,但是牺牲了 RowKey 的有序性。
- 时间戳反转:一个常见的数据处理问题是快速获取数据的最近版本,使用反转的时间戳作为 RowKey 的一部分对这个问题十分有用,可以用 Long.MAX_VALUE - timestamp 追加到 Key 的末尾。
其他建议
尽量减少行和列的大小。在 HBase 中,Value 永远和它的 Key 一起传输的。当具体的值在系统间传输时,它的 RowKey、列名、时间戳也会一起传输。如果你的 RowKey 和列名很大,甚至可以和具体的值相比较,那么你将会遇到一些有趣的问题。
- 增加 Block 大小使得 StoreFiles 索引再更大的时间间隔增加。
- 修改表的模式以减小 RowKey 和列名的大小。
- 压缩也有助于更大的索引。
列族尽可能越短越好,最好是一个字符。
冗长的属性名虽然可读性好,但是更短的属性名存储在 HBase 中会更好。

