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、推薦系統算法以及源碼解析等,送給每一位大數據小伙伴,讓自學更輕松。這里不止是小白聚集地,還有大牛在線解答!歡迎初學和進階中的小伙伴一起進群學習交流,共同進步!
最后祝福所有遇到瓶頸的大數據程序員們突破自己,祝福大家在往后的工作與面試中一切順利。