hbase预分区设置引发的血案

时间:2023-01-31 11:58:59

问题发现

年前数据中台新接入了一张表,监控日志发现,该表 hive ods 表映射过程中,占用的资源非常之大,可以说剩余多少资源,它就能吃掉所有资源,以至于同时段运行的任务全部失败,我是非常的闹心呀。

问题定位

自己左分析右分析,也没弄出个123出来,便请教了一下同事。同事分析后,问我 hbase 建表的时候有没有进行 ​​预分区​​,啥玩意?这完全超出了我的知识边界,(小声逼逼:够水的。。。)。

果不其然,在 hbase 控制台 ​​192.168.0.101:60010/tablesDetailed.jsp​​ 看到,这个表仅用到了一个  Region Server,而数据量非常大(我查了下一共两亿多条),这么大的数据量只用一台服务器处理,集群的优势丝毫没能体现,怪不得这么慢。

hbase预分区设置引发的血案


hbase 预分区

hbase 基本介绍

hbase 表创建时,默认分配某个 region server 的一个 region,所有的写入的查询都是操作的这个 region ,数据量小的时候没用什么问题,数据量达到一定程度时(一般是 10G),会进行分裂 split,这种分裂也只是新增一个 region ,如此一来,集群中的其他 region server 就会处于一个比较闲的状态,集群就达不到负载均衡的效果了。这就是预分区特性的由来。

预分区可以有如下几个有点:

  • 提供数据操作效率(读和写);
  • 使得集群处于负载均衡的状态,防止数据倾斜;
  • 便于容灾调度 region;
  • 优化 map 数量

hbase 预分区设计及制定

hbase 预分区一般采用 2 位数字前缀,即:10,20,30,40,50,60,70,80,90,(第一个分区没用 Start Key,最后一个分区没用 End Key,所以是 10 个分区)。

设置命令如下:

create 'test:student', 'data',{SPLITS => ['10|','20|','30|','40|','50|','60|','70|','80|','90|']}

也可以使用 16 进制序列设置预分区。

设置命令如下:

create 'test:student', 'data', {NUMREGIONS => 15, SPLITALGO => 'HexStringSplit'}

此时,其预分区是 11111111 ~ ffffffff,(第一个分区没用 Start Key,最后一个分区没用 End Key,所以是 16 个分区)。

需要特别注意的是预分区的设计和 hbase rowkey 的设计紧密相关,因为良好的 rowkey 设计能够确保数据能够均匀的命中不同的 region ,从而避免 ​​数据写入热点​​ 的产生,实现写请求的负载均衡。

仔细观察问题表的 rowkey,其前缀是日期的反转,某个日期的数据会落地到相同的 region,这显然是不合理,因为总是写入一个 region,经过分析,将 rowkey 前缀调整为数据接入时间戳的反转,反转之后,rowkey 的前缀是均匀分布的,完美解决了之前的问题。

问题处理

确定问题之后,就可以进行对症处理了,这个问题的根本原因是 hbase 表未设置预分区且 rowkey 设计不合理,两个问题一并处理,hbase 设置预分区需要重建表,rowkey 需要修改代码,重新部署程序,经过梳理,问题处理步骤如下:

  1. 删除 hive middle 库中的对应表
use middle;
drop table student;
  1. 停止 student 数据接入相关程序(先停程序再操作 hbase 表)
  2. 由于想保留 hbase 表数据,所以要将其数据进行备份(通过快照实现)

需要特别注意的是:快照操作过程中,不能填写命名空间,否则会报错。

disable 'test:student'

snapshot 'test:student', 'student_Snapshot'

clone_snapshot 'student_Snapshot', 'test:student_bak'

delete_snapshot 'student_Snapshot'

drop 'test:student'
  1. 重建 hbase 表
create  'test:student', 'info',{SPLITS => ['10|','20|','30|','40|','50|','60|','70|','80|','90|']}
  1. 修改 student 数据接入程序中的 rowkey 设计,前缀调整为数据接入时间戳反转,并重新进行打包、部署及上线。
  2. 查看 student 数据接入情况是否正常。
  3. hbase 控制台查看 Region Server 情况,发现其 region server 由一个变为多个。
  4. 重启执行 hive ods 表映射 shell,占用资源明细减少,操作时间明显缩短,问题解决。

问题总结

hbase 预分区可以说是我的知识盲区(不知道自己不知道的知识),要学习的内容还是由很多呀,加油干吧,小伙子。