1、为什么Rowkey这么重要1.1、Rowkey是什么1.2、Rowkey的作用- 读写数据通过Rowkey找到对应的Region;
- MemStore中的数据按RowKry字典顺序排序;
- HFile中的数据按Rowkey字典顺序排序
1.3、Rowkey对查询的影响举个栗子—Rowkey : uid+phone+name很好支持的数据的检索
- uid = 001 AND phone=12345678901 AND name = zhang
- uid = 001 AND phone=123?
- uid = 001
不太好支持的数据的检索
- phone=12345678901 AND name = zhang
- phone=12345678901
- name = zhang
1.4、Rowkey对Region划分的影响Hbase表的数据是按照Rowkey来分散到不同的Region,不合理的Rowkey设计会导致热点问题的产生。
热点问题是大量的Client直接访问集群的一个或极少数节点,而集群中其他节点处于相对空闲状态。
2、Rowkey设计技巧2.1、Rowkey的设计-Salting- Salting的原理是将固定长度的随机数放在行键起始处
- 优缺点
- 由于前缀随机生成,因而如果想要按照字典顺序找到这些行,则需要做更多的工作。从这个角度上看,salting增加了写操作的吞吐量,却也增大了读操作的开销。
2.2、Rowkey的设计 - HashingHashing 的原理是计算Rowkey的hash值,然后取hash的部分字符串和原来的Rowkey进行拼接
优缺点
- 可以一定程度打散整个数据集,但是不利于scan操作;
- 比如使用md5算法来计算Rowkey的md5值,然后截取前几位字符串,如下:
- substring(MD5(设备ID),0,x)+ 设备ID,其中x一般取5或6
2.3、Rowkey的设计 - Reversing- Reversing的原理是反转一段固定长度或者全部的键
2.4、Rowkey的长度- Rowkey可以是任意的字符串,最大长度是64KB。建议越短越好,原因如下
- 数据的持久化文件HFile是按照KeyValue存储的,如果rowkey过长,比如超过100字节,1000w行数据,rowkey就要占用100*1000w = 10亿个字节,将近1G数据,这样会极大影响HFile的存储效率;
- MemStore将缓存部分数据到内存,如果rowkey字段过长,内存的有效利用率就会降低,系统不能缓存更多的数据,这样会降低检索效率;
- 目前操作系统都是64位系统,系统8字节对齐,控制在16个字节,8字节的整数倍利用了操作系统的最佳特性。
3、Rowkey设计案例剖析3.1、交易类表Rowkey设计-1- 查询某个卖家某段时间内的交易记录
- sellerId + timestamp + orderId
- 查询某个买家某段时间内的交易记录
- buyId + timestamp + orderId
- 根据订单号查询
3.2、交易类表Rowkey设计-1- 如果某个商家卖了很多商品,怎么设计Rowkey实现快速搜索?
- salt + sellerId + timestamp 其中,slat是随机数。
- 可与支持的场景:
- 全表Scan
- 按照sellerId查询
- 按照sellerId + timestamp 查询
3.3、金融风控Rowkey设计- 查询某个用户的用户画像数据
- prefix + uid
- prefix + idcard
- prefix +tele
其中prefix = substr(md5(uid),0,x)
3.4、车联网Rowkey设计- 查询某辆车在某个时间范围的交易记录
- 某批次的车太多,造成热点
- prefix + carId + timestamp
其中prefix = substr(md5(uid),0,x)
3.5、倒序时间戳- 查询用户最新的操作记录或者查询用户某段时间的操作记录
- uid + Long.Max_Value - timestamp
- 查询用户最新的操作记录
- Scan 【uid】 startRow 【uid】【000000000000】stopRow 【uid】【Long.Max_Value - timestamp】
- 查询用户某段时间的操作记录
- Scan 【uid】 startRow 【uid】【Long.Max_Value - startTime】stopRow 【uid】【Long.Max_Value - endTime】
3.6、OpenTSDB的Rowkey设计-1- OpenTSDB定义每个时间序列数据需要包含以下属性
hm
3.6、OpenTSDB的Rowkey设计-2- OpenTSDB提供查询功能
- 指定指标名称和时间范围,给定一个或多个标签名称和标签的值作为条件,查询所有的数据。
- a. proc.loadavg.1m (host=, pool=)(1436331600 <= timestamp < 1436335200):
- 查询13点到14点之间,所有机器所有pool上的虚拟文件系统负载;
- b. proc.loadavg.1m (host=host1, pool=*)(1436331600 <= timestamp < 1436335200):
- 查询13点到14点之间,host1机器所有pool上的虚拟文件系统负载;
- c. proc.loadavg.1m (host=host1, pool=0)(1436331600 <= timestamp < 1436335200):
- 查询13点到14点之间, host1机器pool=0的虚拟文件系统负载。
3.6、OpenTSDB的Rowkey设计-3- OpenTSDB的Rowkey:slat + metric_uid + timetamp + tagk1 + tagv1 + [tankN + tagvN]
3.7、Hbase二级索引