Hbase预分区

櫰木2年前技术文章679


HBase 的数据物理存储格式为多维稀疏排序 Map, 由 key 及 value 组成:

  • key 的构成: rowkey+column family+column qualifier+timestamp+type

  • value 的构成:字节形式存储

在 key 中的 rowkey 可以唯一标识一行记录,因此 HBase 的查询有以下几种实现方式:

  1. 通过 get 方式,指定 rowkey 获取唯一一条记录;

  2. 通过 scan 方式,设置 STARTROW 和 ENDROW 参数进行范围匹配;

  3. 全表扫描,即直接扫描整张表中所有行记录。

HBase 是通过 rowkey 来进行查询的,rowkey 设计的优劣会直接影响读写性能。一般 rowkey 上都会存放一些比较关键的检索信息,我们需要提前规划好数据具体要如何查询,根据查询方式进行数据存储格式的设计,避免做效率特别低的全表扫描。

那如何才能设计出既符合业务使用逻辑,又能满足系统性能需求的 rowkey 呢?

1预分区

在介绍 rowkey 设计之前,先来了解 HBase 的预分区,因为预分区跟 rowkey 设计密不可分。rowkey 设计完成后,需要通过预分区来落地实现。

1.1HBase 的 split 机制

通常 HBase 会自动处理 Region 的拆分操作,当 Region 的大小到达一定阈值后,会把过大的 Region 一分为二,之后在两个 Region 中都能继续增长数据。这就是 HBase 的 split 机制。

HBase 默认的 Region split 策略是,根据以下公式确定 split 的 maxFileSize:

min(r2flushSizemaxFileSize)

其中,r为在线 Region 个数,maxFileSize由参数hbase.hregion.max.filesize指定,默认为 10G.

这里假设 flushSize 为 128M,maxFileSize 为默认的 10G,看看 split 的过程:

第一次拆分大小为:min(1*1*128M, 10G)=128M 第二次拆分大小为:min(3*3*128M, 10G)=1152M 第三次拆分大小为:min(5*5*128M, 10G)=3200M 第四次拆分大小为:min(7*7*128M, 10G)=6272M 第五次拆分大小为:min(9*9*128M, 10G)=10G 第六次拆分大小为:min(11*11*128M, 10G)=10G ...

可以看到,只有在第五次之后的拆分大小才为设定的 10G. 因此hbase.hregion.max.filesize 设置得越大,其 split 的上限大小就会越大。

在 HBase 的这个 split 的过程当中,会出现两个问题:

第一,就是我们所说的热点问题(下面会详细介绍),数据会继续往一个 Region 中写,出现写热点问题;

第二,则是拆分合并风暴,当用户的 Region 大小以恒定的速度增长,Region 的拆分会在同一时间发生,因为同时需要压缩 Region 中的存储文件,这个过程会重写拆分后的 Region,这将会引起磁盘 I/O 上升 。

对于拆分合并风暴,通常需要关闭 HBase 的自动管理拆分,然后手动调用 HBase 的 split 和 major_compact,来分散 I/O 负载。但是其中的 split 操作同样是高 I/O 的操作。

1.2 预分区的意义

为了解决这些问题,预分区就是一种很好的方法,通常预分区可以和 rowkey 的设计结合起来使用。

所谓预分区,就是预先创建 HBase 的表分区。在 HBase 中,每一个 Region 维护着 startRowKey 与 endRowKey,如果加入的数据符合某个 Region 维护的 rowkey 范围,则该数据会交给这个 Region 进行维护。因此可以通过预分区,避免出现 split 过程中的热点问题和拆分合并风暴。

在进行预分区之前,需要明确 rowkey 的取值范围和构成逻辑,将数据要存放的分区大致规划好。分区数量建议为 RegionServer 服务器的倍数,这样能保证每个 RegionServer 上的 Region 数量尽可能一样,均衡分布。

例如,rowkey 为:a-abc001、b-abc002、c-abc003,那么预分区就可以设定为:( ,a)、[a,b)、[b,c)、[c, ).

1.3 预分区的方法

1.3.1. 手动设定预分区

可在 HBase Shell 中使用以下语句,创建表的同时手动设定预分区:

create 'default:table', 'CF', 'partition', SPLITS => []

例如,手动设定 10000 - 50000 的预分区:

create 'default:test1', 'info', 'partition1', SPLITS => ['10000','20000','30000','40000','50000']

在 HBase Web 页面上查看新建表的预分区:

iShot_2023-10-09_14.28.28.png

图1-3-1:查看手动设定的预分区

可以看到,新建的表 Employee 被预先分成了 6 个分区,每个 RegionServer 各分配到两个分区。

1.3.2. 使用十六进制序列预分区

可在 HBase Shell 中使用以下语句,创建表的同时使用十六进制序列生成预分区:

create 'default:test1', 'info', 'partition1', SPLITS => ['10000','20000','30000','40000','50000']

在 HBase Web 页面上查看新建表的预分区:

iShot_2023-10-09_14.28.28.png

图1-3-2:查看十六进制序列预分区

可以看到,新建的表test1 被预先分成了分区

相关文章

prometheus黑盒监控

prometheus黑盒监控

黑盒监控即以用户的身份测试服务的外部可见性,常见的黑盒监控包括 HTTP探针、TCP探针、Dns、Icmp等用于检测站点、服务的可访问性、服务的连通性,以及访问效率等。prometheus提供了bla...

MySQL DDL 风险评估

MySQL DDL 风险评估

一、前言变更是数据库离不开的话题,从 MySQL 5.6 开始,推出 online DDL 即变更期间不锁表,本篇文章介绍 MySQL 变更对数据库的影响如何去判断。二、DDL 风险提示1. 变更速查...

数据湖技术之iceberg(十二)Flink与Iceberg整合-SQL API操作

数据湖技术之iceberg(十二)Flink与Iceberg整合-SQL API操作

1.SQL API 创建Iceberg表并写入数据StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnv...

开启cgroup

开启cgroup

Control groups 是 Linux 内核提供的一种可以限制、记录、隔离进程组所使用的的物理资源的机制。Cgroup 子系统:blkio、CPU、cpuacct、cpuset、devices、...

trino容器对接ldap(二)

trino容器对接ldap(二)

前提:本文前提是在trino容器已经对接上hive组件,并且ldap已经部署完成的基础上进行的对接。前提文章见:helm安装部署trino对接hive(一)安装部署1、设置证书因为不确定是在哪台机器中...

kafka常见配置参数解析

broker.idbroker 的全局唯一编号,不能重复,只能是数字num.network.threads=3处理网络请求的线程数量num.io.threads=8用来处理磁盘 IO 的线程数量soc...

发表评论    

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。