当前位置: 首页 > article >正文

【大数据学习 | HBASE高级】rowkey的设计,hbase的预分区和压缩

1. rowkey的设计

RowKey可以是任意字符串,最大长度64KB,实际应用中一般为10~100bytes,字典顺序排序,rowkey的设计至关重要,会影响region分布,如果rowkey设计不合理还会出现region写热点等一系列问题。

rowkey设计原则:

  1. 保证rowkey的唯一性:性质与主键唯一一致。

  2. 能满足需求的情况下,长度越短越好:推荐16字节

  3. 高位散列:高位散列的目的是使数据均匀分布到不同的region上,散列方式一般采用"反转"、"加盐"、"MD5"的方式对高位进行处理。(防止写热点问题)

需求:hbase存储的是用户的交易信息, 我想查某个用户在某个时间段内的交易记录,如何设计rowkey

用户id(md5), 用户名称, 交易时间, 交易金额, 交易说明

用户id(md5), 交易时间

rowkey设计: 用户id(md5) + _ + 交易时间

create 'hainiu:flow', 'cf'

put 'hainiu:flow', '02f5adff232b37422fc846cc5c1d8328_20211210110000', 'cf:name', 'user1'
put 'hainiu:flow', '02f5adff232b37422fc846cc5c1d8328_20211210110000', 'cf:amt', '1000'
put 'hainiu:flow', '02f5adff232b37422fc846cc5c1d8328_20211210110000', 'cf:time', '2021-12-10 11:00:00'

put 'hainiu:flow', '02f5adff232b37422fc846cc5c1d8328_20211210120000', 'cf:name', 'user1'
put 'hainiu:flow', '02f5adff232b37422fc846cc5c1d8328_20211210120000', 'cf:amt', '2000'
put 'hainiu:flow', '02f5adff232b37422fc846cc5c1d8328_20211210120000', 'cf:time', '2021-12-10 12:00:00'

put 'hainiu:flow', '02f5adff232b37422fc846cc5c1d8328_20211210130000', 'cf:name', 'user1'
put 'hainiu:flow', '02f5adff232b37422fc846cc5c1d8328_20211210130000', 'cf:amt', '3000'
put 'hainiu:flow', '02f5adff232b37422fc846cc5c1d8328_20211210130000', 'cf:time', '2021-12-10 13:00:00'

put 'hainiu:flow', '02f5adff232b37422fc846cc5c1d8328_20211210140000', 'cf:name', 'user1'
put 'hainiu:flow', '02f5adff232b37422fc846cc5c1d8328_20211210140000', 'cf:amt', '4000'
put 'hainiu:flow', '02f5adff232b37422fc846cc5c1d8328_20211210140000', 'cf:time', '2021-12-10 14:00:00'

# 查询 某个人在 20211210 日 11 点 到 20211211 日 12:30 间的交易记录
scan 'hainiu:flow', {STARTROW => '02f5adff232b37422fc846cc5c1d8328_2021121011' , STOPROW=> '02f5adff232b37422fc846cc5c1d8328_202112101230'}

我们可以发现数据已经可以按照范围查询了。

有的时候我们的单点查询比较频繁,那么我们将数据按照散列形式打散然后穿插到不同的region中可以有效的防止读和写热点问题

有时候我们查询的数据是范围性的扫描,这样时候我们就要知道数据必须要有相似的前缀,这样非常好按照范围查询,防止多region扫描问题的产生,比如人口普查数据,我们最好按照省份开头一样,这样的数据范围性比较好查询。

但是这个时候会出现数据倾斜或者热点问题,所以我们在这个基础上还可以实现预分区的设计,在设定表的时候指定分区的数据范围,保证数据的分布均匀

2. hbase的预分区

为了解决数据的倾斜问题,或者数据在刚开始插入的数据都在一个region中,使得一个region中的压力太大,我们可以预先设定一个表数据的分区范围,让数据更加均匀的分布在不同的分区中,或者我们在做数据分类的时候可以按照不同的类别将数据放入到不同的region中扫面数据的时候会比较容易,防止跨多个分区进行操作查询。

预分region需要考虑两个因素,即region个数与region大小。

  • region个数

官方推荐region个数计算公式:

(RS Xmx * hbase.regionserver.global.memstore.size) / (hbase.hregion.memstore.flush.size * column familys)

其中:

RS Xmx:regionserver堆栈内存大小,官方推荐每台regionserver内存大小设置20-24G,不推荐设置更大,因为更大的堆栈内存GC效率较低。

hbase.regionserver.global.memstore.size:为整个regionserver中memstore总大小占用总内存的比例,一般默认为0.4

hbase.hregion.memstore.flush.size:为memstoreflush阈值,一般默认128,可以自己设置

column familys:为列族数

例:(20G*0.4)/(128M*2)=32

官方推荐每个regionserver上region个数在20-200之间。

  • region大小

单个region官方推荐大小为5-10GB,可以通过hbase.hregion.max.filesize设置,当超过该值后会触发split,与region split策略相关。

# 首先我们需要创建预分区文件
# 比如我们做人口普查,需要将不同省份的数据放入到不同的region中
河北省,山西省,吉林省,辽宁省,黑龙江省,陕西省,甘肃省,青海省,山东省,福建省,浙江省,台湾省,河南省,湖北省,湖南省,江西省,江苏省,安徽省,广东省,海南省,四川省,贵州省,云南省
#首先我们按照这些省份的字典顺序将字母排序
云南省
台湾省
吉林省
四川省
安徽省
山东省
山西省
广东省
江苏省
江西省
河北省
河南省
浙江省
海南省
湖北省
湖南省
甘肃省
福建省
贵州省
辽宁省
陕西省
青海省
黑龙江省
# 然后将这些数据放入到一个文件中 /home/hadoop/split.txt
create 'hainiu:advance_split_region', 'cf', {SPLITS_FILE => '/home/hadoop/split.txt'}

由图,存在24个分区。

3. hbase的压缩

建表时指定压缩格式,开启压缩后可以非常有效的缓解hbase数据膨胀问题

create 'hainiu:flow',{NAME => 'cf',VERSIONS => 3,COMPRESSION => 'SNAPPY'}, {SPLITS_FILE => '/tmp/advance_split_region_file'}

如果建表没指定压缩格式,那需要修改列族支持,步骤如下:

1) disable 'hainiu:flow'

如果表的数据量很大,region很多,disable过程会比较缓慢,需要等待较长时间。过程可以通过查看hbase master log日志监控。

2) alter 'hainiu:flow', NAME => 'cf', COMPRESSION => 'snappy'

NAME即column family,列族HBase修改压缩格式,需要一个列族一个列族的修改。名字一定要与你自己列族的名字一致,否则就会创建一个新的列族并且压缩格式是snappy的。

3)enable 'hainiu:flow'

重新enable上线flow表

4)major_compact 'hainiu:flow'

enable表后,HBase表的压缩格式并没有生效,还需要执行一个命令,major_compact。

Major compact除了做文件Merge操作,还会将其中的delete项删除


http://www.kler.cn/a/394061.html

相关文章:

  • change buffer:到底应该选择普通索引还是唯一索引
  • arcgis做buffer
  • 【大数据学习 | HBASE高级】rowkey的设计,hbase的预分区和压缩
  • Spring Boot 2.x 和 Druid 多数据源整合 dm
  • 一文简单了解Android中的input流程
  • vue2+ element ui 集成pdfjs-dist
  • redis 原理篇 31 redis内存回收 内存淘汰策略
  • 【混沌系统】洛伦兹吸引子-Python动画
  • vueRouter路由切换时实现页面子元素动画效果, 左右两侧滑入滑出效果
  • 数据分析编程:SQL,Python or SPL?
  • 机器学习—为什么我们需要激活函数
  • 分享 | 中望3D 2025发布会提及的工业数字化MBD是什么?
  • 本溪与深圳市新零售产业互联协会共商世界酒中国菜湾区农业发展
  • 力扣257:二叉树的所有路径
  • adb不识别设备(手机)的若干情形及解决方法
  • 研究生如何远控实验室电脑?远程办公功能使用教程
  • 论文学习_Efficient Algorithms for Personalized PageRank Computation: A Survey
  • 【案例】定性数据分析软件NVivo 在医疗保健领域的应用
  • A034-基于Spring Boot的供应商管理系统的设计与实现
  • Excel筛选的操作教程
  • ThreadLocal原理及其内存泄漏
  • AI云产品,缺运维技术指南
  • 区块链智能合约开发:全面解析与实践指南
  • 在使用ipc通信时 ,在渲染进程的Vue + TypeScript 开发过程,给window对象添加属性并赋值时,发生报错解决方法
  • docker打包nginx版wordpress
  • Spring Boot基础教学:开发工具和环境