HBase源码系列之compaction

像hbase这种基于LSM的架构,compaction是其中很重要一个环节。

触发compaction

  1. 手工出发

  2. chore线程

    1. CompactionChecker里判断 「s.needsCompaction() 和 s.isMajorCompaction()」
  3. flush触发

执行compaction

​ 此处才是本文的重点,上面的触发更多是条件的判断,不过也很重要(对于线上系统的运维和问题定位解决)此张章节会来较详细讨论HBase的compaction的有关源码方面的一些记录。

​ 首先调用的是如下方法,生成CompactionContext构造CompactionRunner放入线程池中。

1
2
private synchronized CompactionRequest requestCompactionInternal(final HRegion r, final Store s,
final String why, int priority, CompactionRequest request, boolean selectNow, User user)

​ 在里面调用

1
boolean completed = region.compact(compaction, store, compactionThroughputController, user);

​ 然后调用相应store的compact方法

1
store.compact(compaction, throughputController, user);

​ 里面一个compact操作具体的步骤如下:

​ 1. 开始合并返回合并的结果。

1
List<Path> newFiles = compaction.compact(throughputController, user);

​ 此方法中一个判断是否是major

1
ScanType scanType = scannerFactory.getScanType(request);

​ 此ScanType传递给了ScanQueryMatcher来做scan类型的判断。

​ 2. 结果写入对应的cf的目录中。

1
sfs = moveCompatedFilesIntoPlace(cr, newFiles, user);

​ 3. 将本次compaction写入HLOG中。

1
writeCompactionWalRecord(filesToCompact, sfs);

​ 4. 更新StoreFileManager的storefiles,去除旧的文件,加入新的文件

1
replaceStoreFiles(filesToCompact, sfs);

​ 5. 此时已经可以安心的文件读取了,最后一步骤就是删除旧的数据

1
completeCompaction(filesToCompact);