HBase:WAL拆分

2018-05-30 13:46 更新

WAL拆分

RegionServer服務(wù)于許多區(qū)域。區(qū)域服務(wù)器中的所有區(qū)域共享相同活動的WAL文件。WAL文件中的每個編輯都包含有關(guān)它屬于哪個區(qū)域的信息。當(dāng)打開區(qū)域時,需要重播屬于該區(qū)域的WAL文件中的編輯。因此,WAL文件中的編輯必須按區(qū)域分組,以便可以重播特定的集合以重新生成特定區(qū)域中的數(shù)據(jù)。按區(qū)域?qū)AL編輯進(jìn)行分組的過程稱為日志拆分。如果區(qū)域服務(wù)器出現(xiàn)故障,它是恢復(fù)數(shù)據(jù)的關(guān)鍵過程。

在群集啟動時由HMaster完成日志拆分,或者在區(qū)域服務(wù)器關(guān)閉時由ServerShutdownHandler完成日志拆分。為保證一致性,受影響的區(qū)域在數(shù)據(jù)恢復(fù)之前不可用。所有WAL編輯都需要在給定區(qū)域再次可用之前恢復(fù)并重播。因此,受到日志拆分影響的區(qū)域在該過程完成之前不可用。

過程:日志分割,分步執(zhí)行

新目錄按以下模式命名:

  1. /hbase/WALs/<host>,<port>,<startcode>目錄被重新命名。重命名該目錄非常重要,因為即使HMaster認(rèn)為它已關(guān)閉,RegionServer仍可能啟動并接受請求。如果RegionServer沒有立即響應(yīng),也沒有檢測到它的ZooKeeper會話,HMaster可能會將其解釋為RegionServer失敗。重命名日志目錄可確?,F(xiàn)有的有效WAL文件仍然由活動但繁忙的RegionServer使用,而不會意外寫入。新目錄根據(jù)以下模式命名:
    /hbase/WALs/<host>,<port>,<startcode>-splitting       

    這種重命名的目錄的例子可能如下所示:

    /hbase/WALs/srv.example.com,60020,1254173957298-splitting
  2. 每個日志文件都被拆分,每次一個。日志拆分器一次讀取一個編輯項的日志文件,并將每個編輯條目放入對應(yīng)于編輯區(qū)域的緩沖區(qū)中。同時,拆分器啟動多個編寫器線程。編寫器線程選取相應(yīng)的緩沖區(qū),并將緩沖區(qū)中的編輯項寫入臨時恢復(fù)的編輯文件。臨時編輯文件使用以下命名模式存儲到磁盤:
    /hbase/<table_name>/<region_id>/recovered.edits/.temp
    該文件用于存儲此區(qū)域的WAL日志中的所有編輯。日志拆分完成后,.temp文件將被重命名為寫入文件的第一個日志的序列ID。要確定是否所有編輯都已寫入,將序列ID與寫入HFile的上次編輯的序列進(jìn)行比較。如果最后編輯的序列大于或等于文件名中包含的序列ID,則很明顯,編輯文件中的所有寫入操作都已完成。
  3. 日志拆分完成后,每個受影響的區(qū)域?qū)⒎峙浣oRegionServer。打開該區(qū)域時,會檢查recoverededed文件夾以找到恢復(fù)的編輯文件。如果存在任何這樣的文件,則通過讀取編輯并將其保存到MemStore來重播它們。在重放所有編輯文件后,MemStore的內(nèi)容被寫入磁盤(HFile),編輯文件被刪除。

處理日志分割期間的錯誤

如果您將該hbase.hlog.split.skip.errors選項設(shè)置為true,則錯誤處理如下:

  • 拆分過程中遇到的任何錯誤都將被記錄。
  • 有問題的WAL日志將被移到hbase rootdir下的.corrupt目錄中,
  • WAL的處理將繼續(xù)進(jìn)行

如果該hbase.hlog.split.skip.errors選項設(shè)置為false默認(rèn)值,則將傳播該異常,并將該拆分記錄為失敗。

拆分崩潰的RegionServer的WAL時如何處理EOFException

如果在拆分日志時發(fā)生EOFException,即使hbase.hlog.split.skip.errors設(shè)置為false,拆分也會繼續(xù)。在讀取要拆分的文件集合中的最后一個日志時,可能會出現(xiàn)EOFException,因為RegionServer可能在崩潰時寫入記錄的過程中。

在日志分割期間的性能改進(jìn)

WAL日志拆分和恢復(fù)可能需要大量資源并需要很長時間,具體取決于崩潰中涉及的RegionServer的數(shù)量和區(qū)域的大小。啟用或禁用分布式日志分割是為了提高日志分割期間的性能。

啟用或禁用分布式日志拆分

分布式日志處理自HBase 0.92開始默認(rèn)啟用。該設(shè)置由hbase.master.distributed.log.splitting屬性控制,可以設(shè)置為true或false,但默認(rèn)為true。

分布式日志拆分,分步執(zhí)行

配置分布式日志拆分后,HMaster控制進(jìn)程。HMaster在日志拆分過程中注冊每個RegionServer,實際拆分日志的工作由RegionServers完成。分布式日志拆分中逐步描述的日志拆分的一般過程在這里仍然適用。

  1. 如果啟用分布式日志處理,則HMaster會在集群啟動時創(chuàng)建拆分日志管理器實例。
    • 拆分日志管理器管理所有需要掃描和拆分的日志文件。
    • 拆分日志管理器將所有日志作為任務(wù)放入ZooKeeper splitWAL節(jié)點( hbase/splitWAL)中。
    • 您可以通過發(fā)出以下zkCli命令來查看splitWAL的內(nèi)容。顯示示例輸出。
      ls /hbase/splitWAL
      [hdfs%3A%2F%2Fhost2.sample.com%3A56020%2Fhbase%2FWALs%2Fhost8.sample.com%2C57020%2C1340474893275-splitting%2Fhost8.sample.com%253A57020.1340474893900,
      hdfs%3A%2F%2Fhost2.sample.com%3A56020%2Fhbase%2FWALs%2Fhost3.sample.com%2C57020%2C1340474893299-splitting%2Fhost3.sample.com%253A57020.1340474893931, 
      hdfs%3A%2F%2Fhost2.sample.com%3A56020%2Fhbase%2FWALs%2Fhost4.sample.com%2C57020%2C1340474893287-splitting%2Fhost4.sample.com%253A57020.1340474893946]
      
      輸出包含一些非ASCII字符。解碼后,它看起來更簡單:
      [hdfs://host2.sample.com:56020/hbase/WALs
      /host8.sample.com,57020,1340474893275-splitting
      /host8.sample.com%3A57020.1340474893900,
      hdfs://host2.sample.com:56020/hbase/WALs
      /host3.sample.com,57020,1340474893299-splitting
      /host3.sample.com%3A57020.1340474893931,
      hdfs://host2.sample.com:56020/hbase/WALs
      /host4.sample.com,57020,1340474893287-splitting 
      /host4.sample.com%3A57020.1340474893946]
      
      該列表表示要掃描和拆分的WAL文件名,這是日志拆分任務(wù)的列表。
  2. 拆分日志管理器監(jiān)視日志拆分任務(wù)和工作人員。拆分日志管理器負(fù)責(zé)以下正在進(jìn)行的任務(wù):
    • 一旦拆分日志管理器將所有任務(wù)發(fā)布到splitWAL znode,它就會監(jiān)視這些任務(wù)節(jié)點并等待它們被處理。
    • 檢查是否有任何排隊等待的分組日志工人。如果發(fā)現(xiàn)沒有響應(yīng)的工作人員所要求的任務(wù),它將重新提交這些任務(wù)。如果由于某些ZooKeeper異常而導(dǎo)致重新提交失敗,則無法使用的工作者將再次排隊等待重試。
    • 檢查是否有未分配的任務(wù)。如果找到,它會創(chuàng)建一個短暫的重新掃描節(jié)點,以便通知每個拆分的日志工作者通過nodeChildrenChangedZooKeeper事件重新掃描未分配的任務(wù)。
    • 檢查已分配但過期的任務(wù)。如果發(fā)現(xiàn)任何東西,它們會再次返回到TASK_UNASSIGNED狀態(tài),以便它們可以重試。這些任務(wù)可能被分配給緩慢的工作人員,或者他們可能已經(jīng)完成。這不是問題,因為日志拆分任務(wù)具有冪等性。換句話說,相同的日志拆分任務(wù)可以被處理多次而不會引起任何問題。
    • 拆分日志管理器不斷監(jiān)視HBase拆分日志節(jié)點。如果任何拆分日志任務(wù)節(jié)點數(shù)據(jù)發(fā)生更改,拆分日志管理器將檢索節(jié)點數(shù)據(jù)。節(jié)點數(shù)據(jù)包含任務(wù)的當(dāng)前狀態(tài)。您可以使用該zkCli get命令來檢索任務(wù)的當(dāng)前狀態(tài)。在下面的示例輸出中,輸出的第一行顯示任務(wù)當(dāng)前未分配。
      get /hbase/splitWAL/hdfs%3A%2F%2Fhost2.sample.com%3A56020%2Fhbase%2FWALs%2Fhost6.sample.com%2C57020%2C1340474893287-splitting%2Fhost6.sample.com%253A57020.1340474893945
      
      unassigned host2.sample.com:57000
      cZxid = 0×7115
      ctime = Sat Jun 23 11:13:40 PDT 2012 
      ...
      
                  
      根據(jù)數(shù)據(jù)更改的任務(wù)的狀態(tài),拆分日志管理器將執(zhí)行以下操作之一:
      • 如果任務(wù)未分配,請重新提交;
      • 如果任務(wù)被分配,則Heartbeat;
      • 如果任務(wù)失敗,請重新提交或失?。?/li>
      • 如果任務(wù)完成時出現(xiàn)錯誤,請重新提交或失??;
      • 如果任務(wù)由于錯誤而無法完成,則請重新提交或失敗;
      • 如果任務(wù)成功完成或失敗,請將其刪除。
    任務(wù)失敗的原因:該任務(wù)已被刪除;該節(jié)點不再存在;日志狀態(tài)管理器無法將任務(wù)的狀態(tài)移至TASK_UNASSIGNED;重新提交的次數(shù)超過了重新提交閾值。
  3. 每個RegionServer的拆分日志工作器執(zhí)行日志拆分任務(wù)。
    每個RegionServer運行一個稱為拆分日志工作器的守護(hù)進(jìn)程線程,它負(fù)責(zé)拆分日志。守護(hù)程序線程在RegionServer啟動時啟動,并注冊自己以觀察HBase znode。如果任何splitWAL znode子項發(fā)生更改,它會通知睡眠工作器線程喚醒并獲取更多任務(wù)。如果工作人員當(dāng)前任務(wù)的節(jié)點數(shù)據(jù)發(fā)生更改,則工作人員將檢查該任務(wù)是否已由其他工作人員執(zhí)行。如果是這樣,工作線程會停止當(dāng)前任務(wù)的工作。工作人員不斷監(jiān)視splitWAL znode。出現(xiàn)新任務(wù)時,拆分日志工作人員將檢索任務(wù)路徑并檢查每個任務(wù)路徑,直到找到未聲明的任務(wù),并嘗試聲明該任務(wù)。如果聲明成功,它將嘗試執(zhí)行該任務(wù)并state根據(jù)拆分結(jié)果更新任務(wù)的屬性。此時,拆分日志工作者會掃描另一個無人認(rèn)領(lǐng)的任務(wù)。拆分日志工作者如何接近任務(wù)
    • 它查詢?nèi)蝿?wù)狀態(tài),只在任務(wù)處于TASK_UNASSIGNED狀態(tài)時采取行動。
    • 如果任務(wù)處于TASK_UNASSIGNED狀態(tài),則工作人員嘗試TASK_OWNED自行設(shè)置狀態(tài)。如果它沒有設(shè)置狀態(tài),另一名工人將嘗試抓住它。如果任務(wù)保持未分配,拆分日志管理器還會要求所有工作人員稍后重新掃描。
    • 如果工作人員成功地完成任務(wù),它會嘗試再次獲取任務(wù)狀態(tài),以確保它真正異步獲取它。同時,它啟動一個拆分任務(wù)執(zhí)行器來完成實際工作:
      • 獲取HBase根文件夾,在根目錄下創(chuàng)建一個臨時文件夾,并將日志文件拆分為臨時文件夾。
      • 如果拆分成功,任務(wù)執(zhí)行程序?qū)⑷蝿?wù)設(shè)置為狀態(tài)TASK_DONE。
      • 如果工作人員捕獲到意外的IOException,則該任務(wù)將設(shè)置為狀態(tài)TASK_ERR。
      • 如果工作人員正在關(guān)閉,請將任務(wù)設(shè)置為狀態(tài)TASK_RESIGNED。
      • 如果任務(wù)是由另一名工作人員完成的,則只需登錄即可。
  4. 拆分日志管理器監(jiān)視未完成的任務(wù)。拆分日志管理器在所有任務(wù)成功完成時返回。如果所有任務(wù)都完成并出現(xiàn)一些故障,則拆分日志管理器將引發(fā)異常,以便日志拆分可以重試。由于異步實現(xiàn),在極少數(shù)情況下,拆分日志管理器會丟失一些已完成任務(wù)的跟蹤。因此,它定期檢查其任務(wù)圖或ZooKeeper中剩余的未完成任務(wù)。如果沒有找到,它會拋出一個異常,以便日志拆分可以馬上重試,而不是掛在那里等待不會發(fā)生的事情。
以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號