1. 奇智爱享首页
  2. 前沿技术
  3. 大数据

HBase漫谈 | HBase分区过多影响&合理分区数量

前段时间总结了一篇关于 HBase 由于分区过多导致集群宕机的文章,感兴趣的同学可以点击原文《HBase案例 | 20000个分区导致HBase集群宕机事故处理》阅读参考。本文重点参考 HBase 官网,从分区过多这个角度出发,进一步聊一聊 HBase 分区过多的影响以及单节点合理分区数量等。

一、HBase 分区概念

接触过 HBase 的同学都知道,HBase 每张表在底层存储上是由至少一个 Region 组成,Region 实际上就是 HBase 表的分区。HBase新建一张表时默认 Region 即分区的数量为 1 ,一般在生产环境中我们都会手动给Table提前做 “预分区”,使用合适的分区策略创建好一定数量的分区并使分区均匀分布在不同 RegionServer 上。一个分区在达到一定大小时会自动 Split ,一分为二。

通常情况下,生产环境的每个 Regionserver 节点上会有很多 Region 存在,我们一般比较关心每个节点上的 Region 数量,主要为了防止 HBase 分区过多影响到集群的稳定性。

二、切入主题:HBase分区过多有哪些影响?

分区过多会带来很多不好的影响,主要体现在以下几个方面。

1、频繁刷写

我们知道 Region 的一个列族对应一个 MemStore ,假设 HBase 表都有统一的1个列族配置,则每个 Region 只包含一个 MemStore 。通常 HBase 的一个 MemStore 默认大小为 128 MB,见参数 hbase.hregion.memstore.flush.size 。当可用内存足够时,每个 MemStore 可以分配 128 MB空间。当可用内存紧张时,假设每个 Region 写入压力相同,则理论上每个 MemStore 会平均分配可用内存空间。

因此,当节点 Region 过多时,每个 MemStore 分到的内存空间就会很小。这个时候,写入很小的数据量就会被强制 Flush 到磁盘,将会导致频繁刷写。频繁刷写磁盘,会对集群 HBase 与 HDFS 造成很大的压力,可能会导致不可预期的严重后果。

2、压缩风暴

因 Region 过多导致的频繁刷写,将在磁盘上产生非常多的 HFile 小文件,当小文件过多时,HBase 为了优化查询性能就会做 Compaction 操作,合并 HFile 减少文件数量。当小文件一直很多的时候,就会出现 “压缩风暴”。Compaction 非常消耗系统 io 资源,还会降低数据写入的速度,严重的会影响正常业务的进行。

3、MSLAB 内存消耗较大

MSLAB(MemStore-local allocation buffer)存在于每个 MemStore 中,主要是为了解决 HBase 内存碎片问题,默认会分配 2 MB 的空间用于缓存最新数据。如果 Region 数量过多,MSLAB 总的空间占用就会比较大。比如当前节点有 1000 个包含 1 个列族的 Region ,MSLAB 就会使用 1.95GB 的堆内存,即使没有数据写入也会消耗这么多内存。

4、Master assign region 时间较长

HBase Region 过多时,Master 分配 Region 的时间将会很长。特别体现在重启 HBase 时 Region 上线时间较长,严重的会达到小时级,造成业务长时间等待的后果。

5、影响 MapReduce 并发数

当使用 MapReduce 操作 HBase 时,通常 Region 数量就是 MapReduce 的任务数,Region 数量过多会导致并发数过多,产生过多的任务。任务太多将会占用大量资源,当操作包含很多 Region 的大表时,占用过多资源会影响其他任务的执行。

三、如何具体计算出 HBase 合理分区数量?

关于每个 RegionServer 节点分区数量大致合理的范围,HBase 官网上也给出了定义:

Generally less regions makes for a smoother running cluster (you can always manually split the big regions later (if necessary) to spread the data, or request load, over the cluster); 20-200 regions per RS is a reasonable range.

可见,通常情况下每个节点拥有 20~200 个 Region 是比较正常的。借鉴于 20~200 这个区间范围,我们接下来具体讨论。

实际上,每个 RegionServer 的最大 Region 数量由总的 MemStore 内存大小决定。我们知道每个 Region 的每个列族对应一个 MemStore ,假设 HBase 表都有统一的 1 个列族配置,那么每个 Region 只包含一个 MemStore 。一个 MemStore 大小通常在 128~256 MB,见参数 hbase.hregion.memstore.flush.size 。默认情况下,RegionServer会将自身堆内存的40%(见参数hbase.regionserver.global.memstore.size)供给节点上所有MemStore使用,如果所有 MemStore 的总大小达到该配置大小,新的更新将会被阻塞并且会强制刷写磁盘。因此,每个节点最理想的 Region 数量应该由以下公式计算(假设 HBase 表都有统一的列族配置):

((RS memory) * (total memstore fraction)) / ((memstore size) * (column families))

其中:

  • RS memory:表示 RegionServer 堆内存大小,即 HBASE_HEAPSIZE 。
  • total memstore fraction:表示所有MemStore占HBASE_HEAPSIZE 的比例,HBase 0.98 版本以后由 hbase.regionserver.global.memstore.size 参数控制,老版本由 hbase.regionserver.global.memstore.upperLimit 参数控制,默认值 0.4 。
  • memstore size:即每个 MemStore 的大小,原生 HBase 中默认 128 M。
  • column families:即表的列族数量,通常情况下只设置 1 个,最多不超过 3 个。

举个例子,假如一个集群中每个 RegionServer 的堆内存是 32 GB,那么节点上最理想的 Region 数量应该是 32768 * 0.4 / 128 * 1 ≈ 102 ,所以,当前环境中单节点理想情况下大概有 102 个 Region 。

这种最理想情况是假设每个 Region 上的填充率都一样,包括数据写入的频次、写入数据的大小,但实际上每个 Region 的负载各不相同,可能有的 Region 特别活跃负载特别高,有的 Region 则比较空闲。所以,通常我们认为 2~3 倍的理想 Region 数量也是比较合理的,针对上面举例来说,大概 200~300 个 Region 算是合理的。

如果实际的 Region 数量比 2~3 倍的计算值还要多,就要实际观察 Region 的刷写、压缩情况了,Region 越多则风险越大。经验告诉我们,如果单节点 Region 数量过千,集群可能存在较大风险。

四、总结

通过上述分析,我们大概知道在生产环境中,如果一个 RegionServer 节点的Region 数量在 20~200 我们认为是比较正常的,但是我们也要重点参考理论合理计算值。如果每个 Region 的负载比较均衡,分区数量在 2~3 倍的理论合理计算值通常认为也是比较正常的。

假设我们集群单节点 Region 数量比 2~3 倍计算值还要多,因为实际存在单节点分区数达到 1000+/2000+ 的集群,遇到这种情况我们就要密切观察 Region 的刷写压缩情况了,主要从日志上分析,因为 Region 越多 HBase 集群的风险越大。经验告诉我们,如果单节点 Region 数量过千,集群可能存在较大风险。

来源:头条@大数据实战演练

发表评论

登录后才能评论

联系我们

在线咨询:点击这里给我发消息

邮件:746891300@qq.com

工作时间:周一至周五,9:00-18:00,节假日休息