像hbase这种基于LSM的架构,compaction是其中很重要一个环节。
触发compaction
手工出发
chore线程
- CompactionChecker里判断 「s.needsCompaction() 和 s.isMajorCompaction()」
flush触发
执行compaction
此处才是本文的重点,上面的触发更多是条件的判断,不过也很重要(对于线上系统的运维和问题定位解决)此张章节会来较详细讨论HBase的compaction的有关源码方面的一些记录。
首先调用的是如下方法,生成CompactionContext构造CompactionRunner放入线程池中。
1 | private synchronized CompactionRequest requestCompactionInternal(final HRegion r, final Store s, |
在里面调用
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); |