1. 程式人生 > >HBase資料持久化之HRegion.flushcache即CF持久化

HBase資料持久化之HRegion.flushcache即CF持久化

  我們從HRegion.flushcache開始分析。由於這個過程還是比較複雜的,因此,在這一節,我們不會分析的太過詳細,只是單單的介紹一下其大體流程,待大家有了整體的把握之後,我們將在下一節詳細介紹其持久化的具體流程。   為了儘可能嚴謹的描述整個流程,小編在講解過程中會貼比較多的圖來描述。   好了,閒話不說,下面我們進入正題:   首先,讓我們來到今天的入口方法HRegion.flushcache:下圖的程式碼不少,但是,並沒有我們今天要介紹的重點。此圖只是用來表示我們今天要講的方法。   其實,重點的入口方法是下圖的框選方法internalFlushcache。由該方法名,我們就可以猜到該方法應該就是我們要找的方法。   接著,讓我們追蹤到該方法內部,看到其呼叫了下圖所示的兩個方法。如下圖所框選的兩個方法。他們都是我們今天要介紹的重量級方法。   第一個方法主要實現的是記憶體快照的建立。(為簡化描述,以後用方法一描述該方法)   第二個方法主要實現了將記憶體中的資料flush到磁碟上。(同理,用方法二描述該方法)   下面,我們來到第一個方法,也就是HRegion.internalPrepareFlushCache。這個方法的內容很多,但是與我們今天流程相關並不是很多,如下圖所示的程式碼:
  這裡,我們簡單看一下WALUtil.writeFlushMarker,並不做深入講解,因為後面的內容還很多,詳情讓我們放到下一節。   接著,我們來到StoreFlusherImpl.prepare。下圖所框選的方法比較重要,因為這是方法一的核心。它為當前的memstore建立了快照,並且呼叫了resetActive方法,重置了memstore中的active成員變數。大家可能不太清楚我為什麼要強調這裡的active成員變數。那麼我們跳過這張圖。   來到DefaultMemStore.snapshot,看一下我特地為大家標註的。首先,根據當前的active建立ImmutableSegment,然後將剛剛建立的ImmutableSegment賦給成員變數snapshot,最後,呼叫resetActive重置了當前的active為MutableSegment。這裡不是很難,就不詳細介紹了,大家有興趣可以追查一下原始碼。
  接下來,讓我們來到今天的另一個重量級方法HRegion.internalFlushCacheAndCommit,由於該方法比較長,內容比較多,這裡我們僅介紹第一張圖,也就是下圖。如下圖所示,我們框選了兩個比較重要的變數prepareResult.storeFlushCtxs、prepareResult.committedFiles。大家可能會對他們有點陌生。沒有關係,讓我們在下面插一張圖稍稍回顧一下   看了下圖,你可能就恍然大悟了,這正是方法一為方法二呼叫做的必要準備。到這裡,大家應該能夠理解我這裡為什麼要將他們二者稱之為兩個重量級方法了。
  接著,讓我們繼續往下走,來到HStore.StoreFlusherImpl.flushCache方法。   繼續來到上圖所示方法的具體呼叫,這裡就實現了對快照的flush。   接著,我們來到今天所介紹的方法中最為複雜的方法。在下圖,我框選的內容比較多,大家不要擔心,我僅介紹其中與我們這一節緊密相關的後三個方法。   首先,我們來到HStore.createWriterInTmp方法。在這個方法中,獲取了familyTempDir路徑。該路徑是regionDir/.tmp/family.getNameAsString()。然後構建了StoreFileWriter。   對於StoreFileWriter的構造方法是比較重要的,特別是其writer的構建,我在下圖特別作了標示。 由於上圖所示的方法比較重要,在這裡,我再附一張圖來說明上圖所示的writer型別,這關乎後面兩個方法的具體呼叫。   接著,我們來到StoreFlusher.performFlush。你可能會對我在下圖標註的sink比較懵逼。但是仔細想一想,你可能就猜到了,這裡的sink正是上面我們重點描述的HFileWriterImpl。也就是說下面呼叫的sink.append正是HFileWriterImpl.append。   下圖所示正是HFileWriterImpl.append。這裡我們就不詳細敘述了,留待下一節具體分析。   接下來,就是真正的持久化方法:finalizeWriter。顯然,在這裡呼叫了writer.close。這裡的writer型別是StoreFileWriter。   繼續往下走,來到StoreFileWriter.close。而這裡的writer正是我們剛剛再三強調的HFileWriterImpl。   在HFileWriterImpl.close方法中,將相關資訊寫入到輸出流。   在最後的finishClose方法中,也正如後面的圖所示,最後呼叫了outputStream.close,完成了輸出流的關閉。也就是說HStore中儲存的CF資訊flush到磁碟上。   這一節描述的資訊量還是很大的,還是希望大家耐心閱讀。在後面的博文中,小編將做更為詳細的描述。   如果大家感覺不錯,希望點一下下面的推薦。你的肯定是小編最大的動力。如果有疑問,也可以傳送郵件至[email protected]