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使用新的檔案