博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
HBase Rowkey设计原则
阅读量:4159 次
发布时间:2019-05-26

本文共 1807 字,大约阅读时间需要 6 分钟。

HBase由于其存储和读写的高性能,在OLAP及时分析中发挥重要作用,HBase的查询只能通过rowkey来查询(rowkey便表示唯一一行记录)

rowkey设计的优劣直接影响读写性能。HBase中的数据是按照rowkey的ASCII字典书序来进行全局排序
举例:

假如有5个RowKey:”012“,"0","123","234","3",按ASCII字典排序后的结果为:"0", "012", "123", "234", "3”

Rowkey排序时会先对比连个Rowkey的第一个字节,结果相同;然后会对比第二个字节,依次类推

由于HBase是通过Rowkey查询的,一般Rowkey都会存一些比较关键的检索信息,查询时会根据查询方式进行数据存储格式的设计,应该避免做去全表查询
1
2
3
4
Rowkey设计原则

Rowkey的唯一原则

必须在设计上保证其唯一性,由于在HBase中数据存储是key-value形式,若HBase中同一张表插入相同的rowkey,则原先的数据会被覆盖,所以一定保证rowkey的唯一性

Rowkey的排序原则

HBase的rowkey是按照ASCII字典顺序有序设计的,我们在设计rowkey时要充分利用这点;比如视频网站上对影片《泰坦尼克号》的弹幕消息,是按照时间倒排序展示在视频里,这个时候我们设计的Rowkey吆喝时间顺序相关。可以使用”Long.MAX_VALUE-”弹幕发表间的long值作为Rowkey的前缀

Rowkey的散列原则

设计的Rowkey应均匀分布在各个HBase节点上,假如Rowkey是按系统时间戳的方式递增,Rowkey的第一部分如果是时间戳信息的话将造成所有新数据都在一个RegionServer上堆积堆积——热点现象

热点问题

热点发生在大量的client直接访问集中在个别RegionServer上(访问可能是读,写或者其他操作),导致单个RegionServer机器自身负载过高,引起性能下降

解决办法solution:
     1、reverse反转
 例子:手机号反转后的字符串作为rowkey,这样避免了以手机号开头比较固定引起的热点问题
    缺点:牺牲了rowkey的有序性

    2、salt加盐

 比如在一个有4个Region的HBase表中,加salt前的rowkey:abc001,abc002,abc003,分别加上a、b、c前缀后的rowkey为a-abc001、b-abc002、c-abc003;可以看到,salting前数据分布在两个rowkey里,salting后数据分布在三个rowkey钟,增加了读写的吞吐量
 缺点:增加了读写开销
    
    3.Hash散列或者Mod
    例子:将上述的rowkey经过hash处理,采用md5散列算法取前4位做前缀
    结果:
9bf0-abc001 (abc001在md5后是9bf049097142c168c38a94c626eddf3d,取前4位是9bf0)
7006-abc002
95e6-abc003
上面几个rowkey数据会分布在3个region中,实际应用场景中,这种设计会使得分区之间更加均衡
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
Rowkey的长度原则

rowkey是一个二进制,rowkey的长度建议在10~100个字节,越短越好

reason:
1) HBase的持久化文件HFile是按照keyvalue存储的,如果rowkey过长比如500个字节,100万散列数据光rowkey就要占用50亿个字节,接近1G数据,极大影响了HFile的存储效率
2)Memstore存储部分数据到内存,如果rowkey字段过长内存的有效利用率会降低,会降低检索效率
1
2
3
总结

在做Rowkey设计时,请先考虑业务是读比写多、还是读比写少,HBase本身是为写优化的,即便是这样,也可能会出现热点问题,而如 果我们读比较多的话,除了考虑以上Rowkey设计原则外,还可以考虑HBase的Coprocessor甚至elastic search结合的方法,无论哪种方 式,都建议做实际业务场景下数据的压力测试以得到最优结果。

 
原文:https://blog.csdn.net/qq_40825218/article/details/84330777 
 

你可能感兴趣的文章
深入入门正则表达式(java) - 命名捕获
查看>>
使用bash解析xml
查看>>
android系统提供的常用命令行工具
查看>>
【Python基础1】变量和字符串定义
查看>>
【Python基础2】python字符串方法及格式设置
查看>>
【Python】random生成随机数
查看>>
【Python基础3】数字类型与常用运算
查看>>
【Python基础4】for循环、while循环与if分支
查看>>
【Python基础6】格式化字符串
查看>>
【Python基础7】字典
查看>>
【Python基础8】函数参数
查看>>
【Python基础9】浅谈深浅拷贝及变量赋值
查看>>
Jenkins定制一个具有筛选功能的列表视图
查看>>
【Python基础10】探索模块
查看>>
【Python】将txt文件转换为html
查看>>
[Linux]Shell脚本实现按照模块信息拆分文件内容
查看>>
idea添加gradle模块报错The project is already registered
查看>>
在C++中如何实现模板函数的外部调用
查看>>
在C++中,关键字explicit有什么作用
查看>>
C++中异常的处理方法以及使用了哪些关键字
查看>>