HBase Compaction(HFile 文件合并)

何为 Compaction

通过 MemStore 的 Flush 机制会生成一个个 HFile 小文件,HFile 小文件如果数量太多会影响读取性能。为了提高读取效率,就需要通过 Compaction 机制将小文件 HFile 合并成大文件,提升读取效率。

Compaction 的作用

在 HBase 的体系架构下, Compaction 有以下核心作用:

  • 合并小文件,减少文件数,稳定随机读延迟(减少读取的 I/O 操作次数)
  • 提高数据的本地化率(本地化率越高,在 HDFS 上访问数据时延迟就越小)
  • 清除无效数据,减少数据存储空间

Compaction 基本工作原理

Compaction 是从一个 Region 的一个 HStore 中选择部分 HFile 文件进行合并。合并原理是,先从这些待合并的数据文件中依次读出 Key/Value,再由小到大排序后写入一个新的文件。之后,这个新生成的文件就会取代之前已合并的所有文件对外提供服务。

HBase 根据合并规模将 Compaction 分为两类

Minor Compaction

选取部分小的、相邻的 HFile,将它们合并成一个更大的 HFile。在这个过程中达到 TTL 过期的数据会被移除,但是被手动删除的数据不会被移除(这种合并触发频率较高)

Major Compaction

将一个 HStore 中所有的 HFile 合并成一个 HFile,这个过程还会完全清理三类无意义数据:被删除的数据、TTL 过期数据、版本号超过设计版本号的数据。在这个过程中被手动删除的数据会被真正地移除,这种合并触发频率较低,默认为7天一次。不过由于MajorCompaction 消耗的性能较大,你不会想让它发生在业务高峰期,建议手动控制 MajorCompaction 的时机。((这种合并触发频率较低)

Minor Compaction 策略

遍历不强调顺序性了,是把所有的文件都遍历一遍之后每一个文件都去考虑。符合条件而进入待合并列表的文件:

该文件 < (所有的文件大小总和‐该文件大小) * 比例因子
  • 如果该文件大小小于最小合并大小(minCompactSize),则连上面那个公式都不需要套用,直接进入待合并列表。最小合并大小的配置项:hbase.hstore.compaction.min.size。如果没设定该配置项,则使用 hbase.hregion.memstore.flush.size。
  • 新的算法不再按文件为单元进行比较了,而是挑出多个文件组合,以组合作为计算单元。挑选组合的条件是:
    被挑选的文件必须能通过以上提到的筛选条件,并且组合内含有的文件数必须大于hbase.hstore.compaction.min(最小组合个数),小于 hbase.hstore.compaction.max(最大组合个数)。
  • 文件太少了没必要合并,还浪费资源;文件太多了太消耗资源,怕机器受不了。挑选完组合后,比较哪个文件组合包含的文件更多,就合并哪个组合。如果出现平局,就挑选那个文件尺寸总和更小的组合。
Compaction 合并 HFile 文件流程

选出待合并的 HFile 集合后,需要再从线程池中选出合适的处理线程,接下来执行合并流程,合并流程主要分为如下几步:

  • 分别读出待合并 HFile 文件的 Key-Value,进行归并排序处理,之后写入 /tmp 目录下的临时文件中
  • 将临时文件移动到对应 HStore 的数据目录
  • 将 Compaction 的输入文件路径和输出文件路径封装为 Key-Value 写入 WALs 日志并打上 Compaction 标记,最后强制执行 sync
  • 将对应 HStore 数据目录下的 Compaction 输入文件全部删除

Major Compaction 策略

Minor Compaction 的目的是增加读性能,而majorCompaction在minorCompaction 的目的之上还增加了一点:真正地从磁盘上把用户删除的数据(带墓碑标记的数据)删除掉。

MajorCompaction 其实就是 MinorCompaction 升级而来的。如果本次 MinorCompaction 包含所有文件,并且达到了足够的时间间隔,则会被升级为 MajorCompaction。判断是否包含所有文件比较简单,判断是否达到了足够的时间间隔则需要根据以下两个配置项综合考虑:

  • hbase.hregion.majorcompaction:majorCompaction 发生的周期(单位是毫秒,默认是7天)
  • hbase.hregion.majorcompaction.jittermajorCompaction:周期抖动参数( 0~1.0 之间的一个指数,调整这个参数可以让MajorCompaction 的发生时间更灵活,默认值是 0.5)

虽然有以上机制控制 MajorCompaction 的发生时机,但是由于 MajorCompaction 时对系统的压力还是很大的,所以建议关闭自动MajorCompaction,采用手动触发的方式,定期进行 MajorCompaction。

关闭的方式就是把 hbase.hregion.majorcompaction 设置为 0,然后自己定义一些定时任务来让 HBase 在非业务高峰期来手动调用MajorCompaction。因为完全不进行 majorCompaction 对集群非常不利。

posted @ 2022-01-28 20:10  追こするれい的人  阅读(552)  评论(0编辑  收藏  举报