隨著資料量的增加,單個partition serve的資料越來越多,效能會逐漸層的糟糕,這時候partition split就閃亮登場了。
HBase的partition split可以通過命令列出發,實現在client/HBaseAdmin.java裡面,其參數包含region,split pointer(Oracele裡面的list partition定製化更強,允許指定PK list來進行partition,不過一般情況下用不到那麼細的水平)
HRegionServer收到partition split 請求後,compactSplitThread.requestSplit會開啟線程嘗試進行split(compaction and split 看起來很像,有共同的入口,但是我想這這兩者是不是直接能結合起來?),具體過程如下:
1. Client發送split request到region server
2. Region server收到split request後:首先做有效性檢查,並選出split point
a) 檢查是否允許做split:如果檔案中包含reference file(意味著剛剛發生過split),則不允許再次split
b) 如果允許split,則挑選split point:挑選size最大的store file(相當於youchao檔案),然後選擇其middle-key,middle-key不是讀一遍檔案,而是直接從檔案的index裡面去找, Items[length/2]
c) 確保parent region的狀態不是close or closing,確保split point是有效(min(key) < split point < max(key))
3. 通過有效性檢查並選出split point之後,正式開始split過程:
a) 在zookeeper上建立ephemeral的entry指示parent region正在splitting
b) 在parent region的檔案夾中建立臨時split dir
c) 關閉parent region(會flush 所有memory store(memory file),等待active compaction結束),從現在開始parent region 不可服務
d) 從本地server上offline parent region,每個region server都維護了一個valid region的list,該步將parent region從該list中移除
e) Split所有的store file(youchao file),這一步為每個檔案做一個reference file,reference file由兩部分組成:
i. 第一部分是源檔案的路徑,第二部分是新的reference file引用源檔案split key以及引用上半截還是下半截;
ii. 舉個例子:源檔案是Table1/storefile.11,split point 是key1, 則split 成兩個子檔案可能可能是Table1/storefile.11.bottom.key1,
Table1/storefile.11.up.key1,表示從key1切開storefile.11後,兩個引用檔案分別引用源檔案的下半部分和上半部分
f) 建立child region:
i. 設定各種屬性,比如將parent region的訪問指標平分給child region,每人一半
ii. 將上面在parent 檔案夾中產生的臨時檔案夾(裡麵包含對parent region的檔案reference)move到表目錄下,現在在目錄層次上,child region已經跟parent region平起平坐了
g) 向系統meta server中寫入parent region split完畢的資訊,並將child region的名字一併寫入(split狀態在meta層面持久化)
h) 分別Open 兩個child region,主要包含以下幾個步驟:
i. 將child region資訊寫入meta server
ii. Load 所有store file,並replay log等
iii. 如果包含reference檔案,則做一次compaction(類似merge),直到將所有的reference檔案compact完畢,這裡可以看到parent region的檔案是會被拆開寫入各個child regions的。
i) 將parent region的狀態由SPLITTING轉為SPLIT,zookeeper會負責通知master開始處理split事件,master開始offline parent region,並online child regions
j) Worker等待master處理完畢之後,確認child regions都已經online,split結束
Split整個過程其實可以分為兩個大步驟:一是將parent region分裂為child regions的資訊記錄到meta中;二是child regions online之前做compaction直到將所有的reference 檔案過濾一遍,以便parent region的檔案夾可以刪除
但是其將所有store file直接分為兩份,我覺得寫入的量大了,其實parent region可以保留的,每次只產生一個daughter region就可以了,然後parent region裡面的無效資料可以在major compaction的時候過濾掉。