hbase动态更改行键设计_谈笑间学会Hbase Rowkey设计

谈笑间学会-Hbase Rowkey设计

1、为什么Rowkey这么重要

1.1、Rowkey是什么

  • 类似于MySQL、Oracle中的主键,用于标示唯一的行

  • 完全是由用户指定的一串不重复的字符串;

  • Hbase中的数据永远数据根据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划分的影响

43a8e334047bf673e2a326cf7e370f04.png

Hbase表的数据是按照Rowkey来分散到不同的Region,不合理的Rowkey设计会导致热点问题的产生。

热点问题是大量的Client直接访问集群的一个或极少数节点,而集群中其他节点处于相对空闲状态。

2、Rowkey设计技巧

2.1、Rowkey的设计-Salting

  • Salting的原理是将固定长度的随机数放在行键起始处

ba2a7c1d219e7cc8459ae67d21b51197.png

  • 优缺点

    • 由于前缀随机生成,因而如果想要按照字典顺序找到这些行,则需要做更多的工作。从这个角度上看,salting增加了写操作的吞吐量,却也增大了读操作的开销。

2.2、Rowkey的设计 - Hashing

  • Hashing 的原理是计算Rowkey的hash值,然后取hash的部分字符串和原来的Rowkey进行拼接

27c6f7e458737f6f3b809f1c68647d21.png

  • 优缺点

    • 比如使用md5算法来计算Rowkey的md5值,然后截取前几位字符串,如下:

    • substring(MD5(设备ID),0,x)+ 设备ID,其中x一般取5或6

    • 可以一定程度打散整个数据集,但是不利于scan操作;

2.3、Rowkey的设计 - Reversing

  • Reversing的原理是反转一段固定长度或者全部的键

cbce19d042d46c2fd00d8115c3945508.png

  • 优缺点

    • 有效打乱了行键,却牺牲了行排序的属性

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

  • 根据订单号查询

    • orderNo

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设计

  • 查询某辆车在某个时间范围的交易记录

    • carId + timestamp

  • 某批次的车太多,造成热点

    • 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定义每个时间序列数据需要包含以下属性

    • 指标名称

    • 时间戳(毫秒或者秒精度)

    • 一组标签

f1c7a74a913e44d64c8d0a8032ec93fd.png

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]f8462a71335393fa2437cf184a87afde.png

3.7、Hbase二级索引

  • 为什么需要二级索引?

63b1fc1b4a4bea3a5fbefd65e98dfb27.png

  • 需求:如何查询phone = 1311111111 的用户呢?

    • 创建二级索引呗?何为二级索引呢?其实就是根据自己的数据过滤条件,创建中间表,索引值为主表Rowkey即可。

b32a1045d75a856a01d1c8a8c88b5f5b.png

  • SQL + OLTP + 二级索引 => Phoenix

  • 全文检索 + 二级索引      => Solr / Es

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值