RegionServer拆分實(shí)現(xiàn)

2018-05-24 14:32 更新

RegionServer拆分實(shí)現(xiàn)

由于寫入請(qǐng)求由區(qū)域服務(wù)器處理,它們累積在一個(gè)名為memstore的內(nèi)存存儲(chǔ)系統(tǒng)中。一旦memstore填充,它的內(nèi)容就會(huì)作為附加的存儲(chǔ)文件寫入磁盤。這個(gè)事件被稱為memstore刷新。當(dāng)存儲(chǔ)文件堆積時(shí),RegionServer會(huì)將它們壓縮成更少、更大的文件。每次刷新或壓縮完成后,該區(qū)域中存儲(chǔ)的數(shù)據(jù)量將發(fā)生變化。RegionServer會(huì)咨詢區(qū)域拆分策略,以確定該地區(qū)是否因?yàn)槠渌呗蕴囟ǖ脑蚨兊锰蠡驊?yīng)該拆分。如果策略建議,則區(qū)域拆分請(qǐng)求排隊(duì)。

從邏輯上講,分割區(qū)域的過程很簡(jiǎn)單。我們?cè)谠搮^(qū)域的密鑰空間找到一個(gè)合適的點(diǎn),我們應(yīng)該將該區(qū)域分成兩半,然后在該點(diǎn)將區(qū)域的數(shù)據(jù)分成兩個(gè)新的區(qū)域。然而,這個(gè)過程的細(xì)節(jié)并不簡(jiǎn)單。當(dāng)發(fā)生拆分時(shí),新創(chuàng)建的子區(qū)域不會(huì)立即將所有數(shù)據(jù)重新寫入新文件。相反,他們創(chuàng)建類似于符號(hào)鏈接文件的小文件,稱為引用文件,根據(jù)拆分點(diǎn)指向父存儲(chǔ)文件的頂部或底部。引用文件與常規(guī)數(shù)據(jù)文件一樣使用,但只考慮一半的記錄。如果不再有對(duì)父區(qū)域的不可變數(shù)據(jù)文件的引用,則只能分割該區(qū)域。這些引用文件通過壓縮逐漸清理,以便該地區(qū)將停止引用其父文件,并且可以進(jìn)一步拆分。

盡管拆分區(qū)域是由RegionServer做出的本地決定,但拆分過程本身必須與許多參與者協(xié)調(diào)。RegionServer在拆分之前和之后通知Master,更新.META.表以便客戶端可以發(fā)現(xiàn)新的子區(qū)域,并重新排列HDFS中的目錄結(jié)構(gòu)和數(shù)據(jù)文件。拆分是一個(gè)多任務(wù)過程。為了在發(fā)生錯(cuò)誤時(shí)啟用回滾,RegionServer會(huì)保留關(guān)于執(zhí)行狀態(tài)的內(nèi)存日志。RegionServer拆分過程說明了RegionServer執(zhí)行拆分所采取的步驟。每個(gè)步驟都標(biāo)有其步驟編號(hào)。來自RegionServers或Master的操作顯示為紅色,而來自客戶端的操作顯示為綠色。

下圖為RegionServer拆分過程:

RegionServer拆分實(shí)現(xiàn)

  1. RegionServer決定在本地拆分區(qū)域,并準(zhǔn)備拆分。拆分已開始。作為第一步,RegionServer獲取表上的共享讀鎖定,以防止在拆分過程中修改架構(gòu)。然后它在zookeeper下的/hbase/region-in-transition/region-name創(chuàng)建一個(gè)znode,并將znode的狀態(tài)設(shè)置為SPLITTING。
  2. Master開始了解znode,因?yàn)樗幸粋€(gè)父region-in-transitionznode的觀察器。
  3. RegionServer在HDFS中的父級(jí)region目錄下創(chuàng)建一個(gè)子目錄.splits。
  4. RegionServer關(guān)閉父區(qū)域并在其本地?cái)?shù)據(jù)結(jié)構(gòu)中將區(qū)域標(biāo)記為離線。拆分區(qū)域現(xiàn)在處于離線狀態(tài)。在這一點(diǎn)上,來到父區(qū)域的客戶端請(qǐng)求將拋出NotServingRegionException??蛻舳藢⒅卦囈恍﹤浞?。關(guān)閉區(qū)域被刷新。
  5. RegionServer在.splits目錄下為子區(qū)域A和B創(chuàng)建地區(qū)目錄,并創(chuàng)建必要的數(shù)據(jù)結(jié)構(gòu)。然后,它會(huì)拆分存儲(chǔ)文件,因?yàn)樗鼤?huì)在父區(qū)域中為每個(gè)存儲(chǔ)文件創(chuàng)建兩個(gè)引用文件。這些引用文件將指向父區(qū)域的文件。
  6. RegionServer在HDFS中創(chuàng)建實(shí)際的區(qū)域目錄,并為每個(gè)子區(qū)域移動(dòng)引用文件。
  7. RegionServer向.META.表發(fā)送一個(gè)Put請(qǐng)求,并將.META.表中的父級(jí)設(shè)置為離線,添加有關(guān)子區(qū)域的信息。在這一點(diǎn)上,.META.中的子區(qū)域?qū)⒉粫?huì)有單獨(dú)的條目??蛻舳藢⒖吹礁竻^(qū)域在掃描.META.時(shí)被拆分。但直到他們出現(xiàn)在.META.其中才會(huì)知道這些子區(qū)域。此外,如果Put到.META.成功后,父區(qū)域?qū)?huì)有效地拆分。如果RegionServer在此RPC成功之前失敗,則Master和下一個(gè)Region Server打開該區(qū)域?qū)⑶宄嘘P(guān)區(qū)域拆分的不干凈狀態(tài)。更新.META.之后,區(qū)域分割將由Master進(jìn)行前滾。
  8. RegionServer并行打開子區(qū)域A和B.
  9. RegionServer將子區(qū)域A和B添加到.META.,連同它承載區(qū)域的信息。拆分區(qū)域現(xiàn)在處于在線狀態(tài)。在此之后,客戶端可以發(fā)現(xiàn)新的區(qū)域并向他們發(fā)出請(qǐng)求??蛻舳嗽诒镜鼐彺?META.條目,但是當(dāng)他們向RegionServer或者.META.發(fā)出請(qǐng)求時(shí),他們的緩存將失效,他們將從.META.中了解新的區(qū)域。
  10. RegionServer更新ZooKeeper中的znode /hbase/region-in-transition/region-name以表示狀態(tài)SPLIT,以便主服務(wù)器可以了解它。必要時(shí),平衡器可以自由地將子區(qū)域重新分配給其他區(qū)域服務(wù)器。拆分事務(wù)現(xiàn)在已完成。
  11. 拆分之后,.META.和HDFS仍將包含對(duì)父區(qū)域的引用。在子區(qū)域中進(jìn)行壓縮重寫數(shù)據(jù)文件時(shí),這些引用將被刪除。主服務(wù)器中的垃圾收集任務(wù)會(huì)定期檢查子區(qū)域是否仍然引用父區(qū)域的文件。否則,父區(qū)域?qū)⒈粍h除。
以上內(nèi)容是否對(duì)您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)