- Hbase 根据合并规模将 Compaction 分为了两类:MinorCompaction 和 MajorCompaction
- Minor Compaction
- 是指选取一些小的、相邻的StoreFile将他们合并成一个更大的StoreFile,在这个过程中不会
处理已经Deleted或Expired的Cell - 但是会处理超过TTL的数据
- 一次Minor Compaction的结果是让小的storefile变的更少并且产生更大的StoreFile。
- 是指选取一些小的、相邻的StoreFile将他们合并成一个更大的StoreFile,在这个过程中不会
- Major Compaction
- 是指将所有的StoreFile合并成一个StoreFile
- 清理三类无意义数据:被删除的数据、TTL过期数据、版本号超过设定版本号的数据。
- 一般情况下,Major Compaction时间会持续比较长,整个过程会消耗大量系统资源,对上层
业务有比较大的影响。因此线上业务都会将关闭自动触发Major Compaction功能,改为手动
在业务低峰期触发。
-
触发compaction的方式有三种:Memstore刷盘、后台线程周期性检查、手动触发。
-
Memstore刷盘
- memstore flush会产生HFile文件,文件越来越多就需要compact。
- 每次执行完Flush操作之后,都会对当前Store中的文件数进行判断,一旦文件数大于配置,就
会触发compaction。 - compaction都是以Store为单位进行的,而在Flush触发条件下,整个Region的所有Store都
会执行compact
-
后台线程周期性检查
- 后台线程定期触发检查是否需要执行compaction,检查周期可配置。
- hbase.server.thread.wakefrequency(默认10000毫秒)
*hbase.server.compactchecker.interval.multiplier(默认1000) - CompactionChecker大概是2hrs 46mins 40sec 执行一次
- hbase.server.thread.wakefrequency(默认10000毫秒)
- 线程先检查文件数是否大于配置,一旦大于就会触发compaction。
- 如果不满足,它会接着检查是否满足major compaction条件,
- 如果当前store中hfile的最早更新时间早于某个值mcTime,
- 就会触发major compaction(默认7天触发一次,可配置手动触发)。
- 后台线程定期触发检查是否需要执行compaction,检查周期可配置。
-
手动触发
- 一般来讲,手动触发compaction通常是为了执行major compaction,一般有这些情况需要手
动触发合并- 是因为很多业务担心自动major compaction影响读写性能,因此会选择低峰期手动触
发; - 也有可能是用户在执行完alter操作之后希望立刻生效,执行手动触发major
compaction; - 是Hbase管理员发现硬盘容量不够的情况下手动触发major compaction删除大量过期数
据;
- 是因为很多业务担心自动major compaction影响读写性能,因此会选择低峰期手动触
- 一般来讲,手动触发compaction通常是为了执行major compaction,一般有这些情况需要手
承载了大量IO请求但是文件很小的HFile,compaction本身不会消耗太多IO,而且合并完成之后对读的
性能会有显著提升。
-
线程池选择
- Hbase CompacSplitThread类内部对于Split、Compaction等操作专门维护了各自所使用的
线程池 - 和Compaction相关的是如下的longCompactions和shortCompactions
- 前者用来处理大规模compaction,后者处理小规模compaction
- 默认值为2 * maxFlilesToCompact * hbase.hregion.memstore.flush.size
- 如果flush size 大小是128M,该参数默认值就是2 * 10 * 128M = 2.5G
- Hbase CompacSplitThread类内部对于Split、Compaction等操作专门维护了各自所使用的
-
合并策略选择
-
Hbase 主要有两种 minor 策略: RatiobasedCompactionPolicy (0.96.x之前)和
ExploringCompactionPolicy(当前默认) -
RatiobasedCompactionPolicy(基于比列的合并策略)
从老到新逐一扫描HFile文件,满足以下条件之一停止扫描
当前文件大小<比当前文件新的所有文件大小总和*ratio(高峰期1.2,非高峰期5)
当前所剩候选文件数<=阈值(默认为3) -
ExploringCompactionPolicy策略(默认策略)
基于Ratio策略,不同之处在于Ratio策略找到一个合适文件集合就停止扫描,而Exploring策略
会记录所有合适的文件集合,然后寻找最优解,待合并文件数最多或者待合并文件数相同的情况下
文件较小的进行合并
-
FIFO Compaction策略
收集过期文件并删除,对应业务的列簇必须设置有TTL
-
Tier-based Compaction策略(分层策略)
针对数据热点情况设计的策略,根据候选文件的新老程度将其划分为不同的等级,每个等级都有对
应的Ratio,表示该等级文件比选择为参与Compation的概率 -
Stripe Compation策略(条纹策略)
将整个Store中的文件按照key划分为多个range,此处称为stripe,一个Stripe内部就类似于
一个小Region,可以执行Minon Compation和major Compation
-
-
执行文件合并
- 分别读出待合并hfile文件的KV,并顺序写到位于./tmp目录下的临时文件中
- 将临时文件移动到对应region的数据目录
- 将compaction的输入文件路径和输出文件路径封装为KV写入WAL日志,并打上compaction
标记,最后强制执行sync
-
将临时文件移动到对应region的数据目录
-
将compaction的输入文件路径和输出文件路径封装为KV写入WAL日志,并打上compaction
标记,最后强制执行sync -
将对应region数据目录下的compaction输入文件全部删除



