easy-algorithm-interview-an.../bigdata/hbase/Hbase rowkey 设计原则.md

3.3 KiB
Raw Blame History

HBase是三维有序存储的三维指的是RowKey(行健)、column key(columnFamily和qualifier)、TimeStamp(时间戳)通过这三个维度我们可以对HBase中的数据进行快速定位。下面我们主要来讨论RowKey的设计原则

HBase中RowKey可以唯一标识一条记录在HBase查询的时候我们有两种方式第一种是通过get()方法指定RowKey条件后获取唯一一条记录第二种方式是通过scan()方法设置诸如startRow和endRow的参数进行范围匹配查找。所以说RowKey的设计至关重要严重影响着查询的效率 RowKey的设计 主要是遵循以下几个原则:

1)、RowKey长度原则RowKey是一个二进制码流可以是任意字符串最大长度为64KB实际应用中一般为10~100bytes存为byte[]字节数组一般设计成定长。建议是越短越好不要超过16个字节。原因一是数据的持久化文件HFile中是按照KeyValue存储的如果RowKey过长比如100字节1000万列数据光RowKey就要占用100*1000万=10亿个字节将近1G数据这会极大影响HFile的存储效率原因二是memstore将缓存部分数据到内存如果RowKey字段过长内存的有效利用率会降低系统将无法缓存更多的数据这会降低检索效率。因此RowKey的字节长度越短越好原因三是目前操作系统大都是64位内存8字节对齐。控制在16个字节8字节的整数倍利用操作系统的最佳特性。

2)、RowKey散列原则如果RowKey是按时间戳的方式递增不要将时间放在二进制码的前面建议将RowKey的高位作为散列字段由程序循环生成低位放时间字段这样将提高数据均衡分布在每个RegionServer实现负载均衡的几率如果没有散列字段首字段直接是时间信息将产生所有数据都在一个RegionServer上堆积的热点现象这样在做数据检索的时候负载将会集中在个别RegionServer降低查询效率。

3)、RowKey唯一原则必须在设计上保证其唯一性。

RowKey是按照字典排序存储的因此设计RowKey时候要充分利用这个排序特点将经常一起读取的数据存储到一块将最近可能会被访问的数据放在一块。

举个例子如果最近写入HBase表中的数据是最可能被访问的可以考虑将时间戳作为RowKey的一部分由于是字段排序所以可以使用Long.MAX_VALUE-timeStamp作为RowKey这样能保证新写入的数据在读取时可以别快速命中。

案例分析:

用户订单列表查询RowKey设计。

需求场景

某用户根据查询条件查询历史订单列表

查询条件

开始结束时间(orderTime)—–必选,

订单号(seriaNum),

状态(status),游戏号(gameID)

结果显示要求

结果按照时间倒序排列。

解答

RowKey可以设计为

userNum$orderTime$seriaNum

这样设计已经可以唯一标识一条记录了订单详情都是可以根据订单号seriaNum来确定。在模糊匹配查询的时候startRow和endRow只需要设置到userNum$orderTime即可如下

startRow=userNum$maxvalue-stopTime

endRow=userNum$maxvalue-startTime

其他字段用filter实现。

本文转载自: http://blog.csdn.net/lzm1340458776/article/details/44941953