首页 > 编程知识 正文

深入理解 HBase Compaction 机制

时间:2023-05-05 09:58:02 阅读:112120 作者:2303

HBase有很多话题,包括读写路径相关的数据结构、性能优化和读写优化设计。 今天讨论的Compaction机制是在HBase体系结构上进行的重要优化,实际上已经有很多文章,例如HBase的体系结构设计、FlushCompaction等等。 本文也主要参考HBase官网、社区的几篇文章进行总结,从各个重点进行总结,旨在帮助我们更好地掌握Compaction机制。

熟悉HBase以执行Compaction的学生,HBase基于LSM-tree (日志结构管理器)存储模式设计。 在写入路径中写入wal ) write-ahead-log ),也就是说,要知道预写日志是在写入后才写入的。随着数据写入的进行,磁盘的HFile文件会增加。 过多的文件会影响HBase查询的性能,主要会增加查询数据的I/o次数。 为了优化查询性能,HBase将合并较小的HFile以减少文件数。 这种合并HFile的操作称为Compaction,是执行Compaction的主要原因。

CompactIOn的作用实际上是CompactIOn操作是资源密集型操作,特别是io密集型操作。 如将在后面叙述的,Compaction实际上是短时间的io消耗以换取相对稳定的读取性能。

Compaction分类HBase Compaction分为Minor Compaction和Major Compaction两种,通常我们简称为小合并、大合并。 下面是一个简单的示意图

(图片来源: https://mm biz.qpic.cn/mm biz _ png/lic vxr 9i B9 M6 D6 sdjxpzxhr 1ic4ldkyicf2q9r9a7slbxnvkomjmdoiazq7dmjwsynkemvv 31 HV9ezy

Minor Compaction :选择几个小的、相邻的HFile,将它们合并为一个大的HFile。 默认情况下,minor compaction会删除所选HFile的TTL过期的数据。

majorcompaction(1 (指将一个存储区中的所有HFile合并为一个HFile。 此过程将清理三种无意义的数据:删除的数据(标记为Delete的数据)、TTL过期的数据和版本号超过设置的版本号的数据。 此外,一般来说,Major Compaction时间较长,整个流程占用大量系统资源,对上层业务影响较大。 因此,在生产环境中,通常关闭自动触发器Major Compaction功能,并将其更改为在业务高峰时手动触发。

这里值得注意的是,默认情况下Minor Compaction也删除数据,但只是删除合并HFile的TTL过期数据。 Major Compaction将永久删除无效数据,例如已删除的数据、TTL过期的数据和版本号过大的数据。

Compaction触发条件HBase触发Compaction的条件有三种: memstore Flush、后台线程周期性检查和手动触发。

memstoreflush :可以说compaction的根本原因在于flush。 当memstore达到一定阈值或其他条件时,会触发flush写入磁盘并生成HFile文件。 正因为HFile文件越来越多,所以需要压缩。 HBase在每次flush时确定是否执行compaction,并在满足minor compaction或major compaction条件时触发执行。

后台线程周期性检查:后台线程CompactionChecker定期检查是否需要运行compaction。 检查周期为h base.server.thread.wake frequency * h base.server.compact checker.inng其中参数h base.server.thread.wwing 这是用于周期性检查log roller、memstore flusher等操作的基于h的服务端线程的唤醒时间间隔; 参数h base.server.compact checker.interval.multiplier的默认值为1000,是compaction操作的周期性检查乘数系数。 10 * 1000 s时间约等于2hrs、46mins、40sec。

手动触发器是通过以下方式之一运行compact、major_compact等命令: h base shell、Master UI界面或HBase API。

Compaction参数分析与Major Compaction参数Major Compaction相关的参数相对较少,主要有较大的合并间隔和抖动参数因子:

1.h base.h region.major compaction

Major compaction周期时间间隔,默认值604800000,单位ms。 表示maj

or compaction默认7天调度一次,HBase 0.96.x及之前默认为1天调度一次。设置为 0 时表示禁用自动触发major compaction。需要强调的是一般major compaction持续时间较长、系统资源消耗较大,对上层业务也有比较大的影响,一般生产环境下为了避免影响读写请求,会禁用自动触发major compaction。

2.hbase.hregion.majorcompaction.jitter

Major compaction抖动参数,默认值0.5。这个参数是为了避免major compaction同时在各个regionserver上同时发生,避免此操作给集群带来很大压力。 这样节点major compaction就会在 + 或 - 两者乘积的时间范围内随机发生。

Minor Compaction 参数

Minor compaction涉及的参数比major compaction要多,各个参数的目标是为了选择合适的HFile,具体参数如下:

1.hbase.hstore.compaction.min

一次minor compaction最少合并的HFile数量,默认值 3。表示至少有3个符合条件的HFile,minor compaction才会启动。一般情况下不建议调整该参数。

如果要调整,不建议调小该参数,这样会带来更频繁的压缩,调大该参数的同时其他相关参数也应该做调整。早期参数名称为 hbase.hstore.compactionthreshold。

2.hbase.hstore.compaction.max

一次minor compaction最多合并的HFile数量,默认值 10。这个参数也是控制着一次压缩的时间。一般情况下不建议调整该参数。调大该值意味着一次compaction将会合并更多的HFile,压缩时间将会延长。

3.hbase.hstore.compaction.min.size

文件大小 < 该参数值的HFile一定是适合进行minor compaction文件,默认值 128M(memstore flush size)。意味着小于该大小的HFile将会自动加入(automatic include)压缩队列。一般情况下不建议调整该参数。

但是,在write-heavy就是写压力非常大的场景,可能需要微调该参数、减小参数值,假如每次memstore大小达到1~2M时就会flush生成HFile,此时生成的每个HFile都会加入压缩队列,而且压缩生成的HFile仍然可能小于该配置值会再次加入压缩队列,这样将会导致压缩队列持续很长。

4.hbase.hstore.compaction.max.size

文件大小 > 该参数值的HFile将会被排除,不会加入minor compaction,默认值Long.MAX_VALUE,表示没有什么限制。一般情况下也不建议调整该参数。

5.hbase.hstore.compaction.ratio

这个ratio参数的作用是判断文件大小 > hbase.hstore.compaction.min.size的HFile是否也是适合进行minor compaction的,默认值1.2。更大的值将压缩产生更大的HFile,建议取值范围在1.0~1.4之间。大多数场景下也不建议调整该参数。

6.hbase.hstore.compaction.ratio.offpeak

此参数与compaction ratio参数含义相同,是在原有文件选择策略基础上增加了一个非高峰期的ratio控制,默认值5.0。这个参数受另外两个参数 hbase.offpeak.start.hour 与 hbase.offpeak.end.hour 控制,这两个参数值为[0, 23]的整数,用于定义非高峰期时间段,默认值均为-1表示禁用非高峰期ratio设置。

Compaction 线程池选择

HBase RegionServer内部专门有一个 CompactSplitThead 用于维护执行minor compaction、major compaction、split、merge操作的线程池。其中与compaction操作有关的线程池称为 largeCompactions(又称longCompactions) 与 smallCompactions(又称shortCompactions),前者用来处理大规模compaction,后者处理小规模compaction,线程池大小都默认为 1 即只分别提供了一个线程用于相应的compaction。
这里并不是major compaction就一定会交给largeCompactions线程池处理。关于HBase compaction分配给largeCompactions还是smallCompactions线程池受参数hbase.regionserver.thread.compaction.throttle控制,该参数默认值为2 * hbase.hstore.compaction.max * hbase.hregion.memstore.flush.size,如果flush size 大小是128M,该参数默认值就是2684354560 即2.5G。一次compaction的文件总大小如果超过该配置,就会分配给largeCompactions处理,否则分配给smallCompactions处理。

largeCompactions与smallCompactions的线程池大小可通过参数 hbase.regionserver.thread.compaction.large、hbase.regionserver.thread.compaction.small进行配置。对于compaction压力比较大的场景,如果要调大两种线程池的大小,建议调整范围在2~5之间,不建议设置过大否则可能会消费过多的服务端资源造成不良影响。

Compaction 策略介绍

HBase的compaction policy准确的说有4种,分别是RatioBasedCompactionPolicyExploringCompactionPolicy、FIFOCompactionPolicy 以及 StripeCompactionPolicy。其中,HBase使用的压缩策略主要就是前两种,HBase 0.96.x版本之前,默认的压缩策略是RatioBasedCompactionPolicy,HBase 0.96.x以及更新版本中,默认为ExploringCompactionPolicy。ExploringCompactionPoliy要比旧版本中的RatioBasedCompactionPolicy 性能更高,因此一般情况下也不建议改变默认配置。各种压缩策略之间更详细的区别不再介绍。

如果在HBase 0.96.x之后仍想配置RatioBasedCompactionPolicy策略,可以通过修改hbase-site.xml添加hbase.hstore.defaultengine.compactionpolicy.class配置项,配置值为RatioBasedCompactionPolicy,恢复默认配置只需移除该配置项即可。

Compaction 对读写请求的影响 存储上的写入放大

HBase Compaction会带来写入放大,特别是在写多读少的场景下,写入放大就会比较明显,下图简单示意了写入放大的效果。

(图片来源:https://mmbiz.qpic.cn/mmbiz_png/licvxR9ib9M6D6sDjXPZxHR1ic4LDKyicf2qfx417fJ8QHmfn82uBhSS1fC4mDqSB67JHzGs6kyqHiccrQEu2ryPKJA/640)

随着minor compaction以及major Compaction的发生,可以看到,这条数据被反复读取/写入了多次,这是导致写放大的一个关键原因,这里的写放大,涉及到网络IO与磁盘IO,因为数据在HDFS中默认有三个副本。

读路径上的延时毛刺

HBase执行compaction操作结果会使文件数基本稳定,进而IO Seek次数相对稳定,延迟就会稳定在一定范围。然而,compaction操作会带来很大的带宽压力以及短时间IO压力。因此compaction就是使用短时间的IO消耗以及带宽消耗换取后续查询的低延迟。这种短时间的压力就会造成读请求在延时上会有比较大的毛刺。下图是一张示意图,可见读请求延时有很大毛刺,但是总体趋势基本稳定。

(图片来源:http://img0.tuicool.com/3m2aIjv.png)

写请求上的短暂阻塞

Compaction对写请求也会有比较大的影响。主要体现在HFile比较多的场景下,HBase会限制写请求的速度。如果底层HFile数量超过hbase.hstore.blockingStoreFiles 配置值,默认10,flush操作将会受到阻塞,阻塞时间为hbase.hstore.blockingWaitTime,默认90000,即1.5分钟,mlddn,如果compaction操作使得HFile下降到blockingStoreFiles配置值,则停止阻塞。另外阻塞超过时间后,也会恢复执行flush操作。这样做可以有效地控制大量写请求的速度,但同时这也是影响写请求速度的主要原因之一。

Compaction 总结

HBase Compaction操作是为了数据读取做的优化,总的来说是以牺牲磁盘io来换取读性能的基本稳定。Compaction操作分为minor compaction与major compaction,其中major compaction消耗资源较大、对读写请求有一定影响,因此一般是禁用自动周期性执行而选择业务低峰期时手动执行。另外本文也重点介绍了操作相关的各个参数,帮助加强对Compaction的理解以及便于后续调参参考。

参考

http://hbase.apache.org/book.html#compaction
https://mp.weixin.qq.com/s/ctnCm3uLCotgRpozbXmVMg
https://blog.csdn.net/cangencong/article/details/72763265
https://blog.csdn.net/shenshouniu/article/details/83902291

往期推荐

1、HBase最佳实践 | 聊聊HBase核心配置参数
2、Apache Hudi:剑指数据湖的增量处理框架
3、Hadoop社区比 Ozone 更重要的事情
4、MapReduce Shuffle 和 Spark Shuffle 结业篇

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。