Compact(合并):是指在HBase中,HRegion上某一个列簇部分或者全部Store File合并。是由于数据不断的被写入,MemStore达到阀值则会把数据flush到Store File持久化。这样样的话就有很多文件,越积越多会严重影响HBase的读取效率,所以HBase在满足一定条件获或者手动触发合并操作,讲很多文件合并成一个大文件
StoreEngine: 是一个能够为HStore操作创建对象的工厂。因为不是所有的compaction政策和store file manager等都兼容,所以将他们通过StoreEngine维系在一起
CompactionRequest: 这个类持有进行compaction操作具体的一些逻辑,或者说是对compact请求的封装
在HRegionServer启动运行的时候,会启动compactSplit线程,以用于split Region和 compact Region上 store files。
一 MemStoreFlush调用flushRegion之后,会根据返回的FlushResult判断是否应该进行compact 或者 split,流程如下:
1.1 boolean shouldCompact =flushResult.isCompactionNeeded(); 判断是否应该进行compact,如果不需要记性split,且需要进行compact,那么才会执行server.compactSplitThread.requestSystemCompaction
1.2 拿到HRegion上的所有store,遍历每一个store,创建Compaction
Request对象
1.3 每一个Store通过selectCompaction创建CompactionContext对象,具体在调用Store#requestCompactionl来创建CompactionContext对象
1.4 会删除一些不需要的文件,这些不需要的文件大都是到期的文件
1.5 根据CompactionPolicy的selectCompaction创建Compaction
Request对象:
首先:从传入的store下的store files中获取合格的store file。
然后:决定当前这个CompactionRequest是否是Major Compaction。
1.6 然后将CompactionRequest中选中的需要compact的文件添加到
filesCompacting
1.7 然后判断大多是compaction是small还是large,然后创建CompactRunner放入到不同longCompactions和shortCompactions线程池
1.8 CompactRunner然后调用HRegion的compact方法,开始真正的compact操作
二 HRegion的compact操作
2.1 首先应该判断HRegion是否下线,如果下线直接返回
2.3 调用store#compact方法,开始compact store file,这个方法可能需要耗费一些时间,所以这个调用线程必须长期阻塞
2.4 Store通过CompactContext获取该Store的CompactionRequest,并从CompactionRequest获取需要合并的文件
2.4 调用CompactContext#compact方法->DefaultCompactor/Stripe
Compactor,我们暂时不考虑StripeCompactor这种情况,使用DefaultCompactor来进行分析
2.4 获取到该store所有scanner中最小的read point,并且根据需要合并的文件 创建StoreFileScanners; 然后创建StoreScanner
2.5 调用performCompaction执行
# 创建一个空的Cell List
# 调用StoreScanner#next方法,将遍历到的Cell填充到Cell List中
# 遍历这个Cell List,然后通过Writer写入文件
# Writer写入文件会有文件路径,最后将这些文件的path添加到一个List,返回
2.6 如果compaction操作完成,就需要将文件移到正确地方,并创建StoreFile和Reader,返回StoreFile列表
2.7 调用writeCompactionWalRecord:在WAL中写入compaction的记录
2.8 调用replaceStoreFiles:
# 移除掉已经被合并的文件,然后将合并之后的文件添加到StoreFileManager
# 从正在合并的文件列表filesCompacting中移除掉已经被合并的文件
2.9 调用completeCompaction完成该Store的compact操作,这个时候Store将会对StoreScanner使用新的文件