HBase FlushCache原理實現
FlushCache時間點
當memstore的位元組數超過hbase.hregion.memstore.flush.size時, Region會發起一次非同步的Flush Region操作, 這次Flush請求其實是放入到一個叫做MemStoreFlusher的佇列中, 這個佇列後面跟著一個執行緒池, 每個執行緒從佇列中取Flush 請求, 然後每個FlushHandler併發地去進行對應的Flush操作. 注意這裡有個引數可以控制FlushHandler的個數,叫做hbase.hstore.flusher.count。
建立snapshot的時候,需要Flush Cache。
關閉Region的時候,需要Flush Cache。
做Region的相關操作,例如Merge/Split操作時,需要FlushCache。

FlushCache流程
加鎖;記錄下當前的sequenceId,並備份Memstore的snapshot;放鎖.
將各個store裡面的memstore都匯出到.tmp目錄下的檔案中.
善後處理. 例如將.tmp目錄下的檔案move到region目錄下; 清理memstore中遺留的snapshot .
在這個過程中,有幾個問題需要考慮:
Flush的各個步驟, 哪些步驟會影響讀寫操作? 那些步驟不會影響 ?
實際上,只有在第1步加鎖拿sequenceId以及備份memstore的時候,是不讓讀寫的(這裡拿的鎖是updatesLock.writeLock()) ,等放鎖之後,memstore其實已經被拆分為兩塊記憶體了,一塊是snapshot表示sequenceId之前的所有資料, 一塊是kvset表示sequenceId之後的所有資料.如果這時候有一個MemstoreScanner需要讀資料,那麼需要把snapshot和kvset兩個集合的資料做歸併之後,按照順序依次返回.在此我向大家推薦一個大資料技術交流圈: 658558542 突破技術瓶頸,提升思維能力 。
Flush和Compaction相互之間關係是什麼?
首先FlushCache必定會導致storeFiles增多,storeFiles越多,compaction的壓力越大。compaction操作越多,磁碟頻寬壓力越大,反過來也會影響flushCache的效率。因此,RegionServer做了一個限制就是當storeFiles個數超過blockingFilesCount的時候,可以讓flush request最多等待blockingWaitTime時長,如果超過這個時長了, storeFiles的個數還是超過了blockingFilesCount,那就直接進行flush操作,不等了。
如果將時間軸按照第3步切分為兩段,一段是之前,一段是之後,那麼之前和之後,scanner操作有什麼變化?
對於第3步之前,snapshot那部分資料是讀記憶體,第3部之後,之前在記憶體中的那部分資料落到磁碟了。如果這期間有一個scan操作,那麼需要在資料落到磁碟的時候,通知這個scan,告知下次讀取資料,必須去磁碟中讀資料,這個通知操作,就是通過ChangedReadersObserver來完成的,其實就是把之前開啟的各種scanner都關閉掉,重新開啟store中個各種scanner(參見StoreScanner.resetScannerStack)。
Flush和Split有什麼關係?
FlushCache會造成一個store落盤的總資料量增加,如果增加到一定閥值(預設是10G),這個store就會造成Region做split操作。對於一個Region中有多個store, 一般是讓資料量最多的store去做splits。具體需要根據Region設定的 RegionSplitPolicy 來定。
感謝您的觀看,如有不足之處,歡迎批評指正。
在此我向大家推薦一個大資料開發交流圈:
658558542 ( ☛點選即可加入群聊 )
裡面整理了一大份學習資料,全都是些乾貨,包括大資料技術入門,大資料離線處理、資料實時處理、Hadoop 、Spark、Flink、推薦系統演算法以及原始碼解析等,送給每一位大資料小夥伴,讓自學更輕鬆。這裡不止是小白聚集地,還有大牛線上解答!歡迎初學和進階中的小夥伴一起進群學習交流,共同進步!
最後祝福所有遇到瓶頸的大資料程式設計師們突破自己,祝福大家在往後的工作與面試中一切順利。