Hadoop架構: 關於Recovery (Lease Recovery , Block Recovery, PipeLine Recovery)


該系列總覽: Hadoop3.1.1架構體系——設計原理闡述與Client源碼圖文詳解 : 總覽

在HDFS中,有三種Recovery

 1.Lease Recovery

 2.Block Recovery

 3.PipeLine Recovery

以下將 一 一 講解。

一.Lease Recovery

首先很有比要介紹一下Lease(租約)

租約保證HDFS的一讀多寫機制,當一個客戶端(Client)希望打開(Open)HDFS中的某個文件進行append或者truncate操作(追加內容或者減少內容)

他必須向NameNode申請Lease(租約),Lease相當於一把寫鎖,只有擁有Lease的客戶端才能對文件進行寫操作,其他客戶端只能對文件進行讀操作,而不能

進行寫操作。當客戶端關閉(Close)文件的時候,NameNode將釋放相應的租約給其他客戶端使用,相當於鎖的釋放。但是,有時候客戶端拿到寫鎖之后可能宕機,無法關閉文件,從而導致租約無法歸還。為了解決這個問題,NameNode中采取一種定時機制,客戶端需要在規定的時間內,續租(Renew The Lease),才能繼續擁有文件寫的權力(聯想一下交房租)。如果客戶端沒有在規定的時間內續租的話,NameNode有權把這個客戶端占有的租約恢復成無人使用狀態,以便給后來需要租約的客戶端使用,恢復租約到無人使用狀態的過程叫做(Lease Recovery)

先闡述一下,上述所說的規定時間。

有兩種規定時間:1.軟限制時間(一般是一分鍾)  2.硬限制時間(一般是一小時)(強制下線時間)

Lease Recovery 在兩種情況下發生

1.一個占有Lease的客戶端在軟限制時間內沒有續租,並且有其他的客戶端表示對他的Lease有興趣。

2.一個占有Lease的客戶端在硬限制時間內沒有續租,在硬限制時間內沒有其他客戶端來過問這個Lease。NameNode將以其他客戶端的名義要回這個Lease。

 

Lease Recovery過程:

假設沒有按期續租的客戶端為A

1.NameNode將以HDFS系統的名義占有租約,如此一來,如果又有客戶端想對正在Lease Recovery的文件上下其手的話,就會失敗,因為NameNode已經占有租約。(具體無法執行的操作包括:針對對應文件向NameNode請求一個新的GS,打開文件讀寫,關閉文件等等

2.NameNode檢查自己這里文件的最后兩個Block的狀態

  

3.NameNode將自己這邊的BLOCK從UNDER_CONSTRUCTION狀態轉換成UNDER_RECOVERY狀態。

4.找到被A寫入的DataNode,可能不只一個DataNode。如果在這些DataNode中找不到對應的Replica或者根本就不存在對應DataNode.則放棄Recovery

5.如果沒有最小備份數個DataNode告知NameNode自己擁有FINALIZED態的Replica(比如我們設置的最小備份數是3,那么理應有3個DataNode告訴NameNode,自己已經有FINALIZED態的Replica了。也就是我們的最小備份數目的達成),將轉到步驟6,否則結束。

6.NameNode隨機選取一個DataNode為領袖DataNode

7.NameNode生成一個新GS,用來做為本次Recovery的標識符,稱為Recovery Id,因為BGS是單調遞增的,所以每次Recovery的GS都獨一無二,如果Recovery成功這個新的GS將成為Block的BGS。NameNode隨后將Replica所在的DataNode,被Recovery的Block的GS,BlockId等信息發送給領袖DataNode。

(GS/BGS,具體見Hadoop架構: HDFS中數據塊的狀態及其切換過程,GS與BGS)

8.領袖DataNode收到上述信息后,將新GS和BlockId發送給上一步獲取的各個DataNode,我們稱之為從仆DataNode吧

9.從仆DataNode工作

    1.檢查自己是否真的如NameNode所說,存在合法的Replica,如果Replica的BGS和NameNode給出的BGS不一樣,則拋出異常。

  2.如果Replica合法,但是正在被其他Writer寫入,那么DataNode將斷打斷這個Writer,並且等待Writer退出,在等待的過程中會把數據寫回磁盤,保證數據量是DR(DR請見:Hadoop架構: 流水線(PipeLine)),如果Writer嘗試重建流水線,將會失敗,因為1中已經提到,NameNode以文件系統的名義占用了租約,其他客戶端無法針對該文件獲得新的GS。這個Writer可能是忘記續租的客戶端。

  3.關閉可能存在的Recovery,在本次Recovery之前可能有別的Recovery正在本文件進行,因為每個Recovery都有一個新的GS來作為獨一無二的標記,所以如果這個原本就有的Recovery的Recovery Id比我們本次Recovery的Recovery Id舊的話,就把原有Recovery的GS設置成設置成本次Recovery的GS

10.領袖DataNode讓所有仆從DataNode的把Replica的BGS都更新為第4步獲得的新BGS,並且將所有的Replica都按情況裁剪成如下長度:

根據所有仆從DataNode的情況選取長度:

11.領袖DataNode根據仆從DataNode的工作情況決定下一步

  1.如果全部仆從DataNode都完成了工作,沒有異常,則直接向NameNode匯報自己完成了工作

  2.如果部分完成了工作,部分沒有完成,則進行重試,超過一定次數后,放棄Recovery

12.NameNode更新關於Block的信息(比如這個塊存在哪些DataNode上,BGS是多少),並且釋放租約

13.NameNode將關於塊的變化(塊長度變成了最小等等,BGS變化等)寫入到日志

 

二,Block Recovery

其中6~11步其實就是Block Recovery , 把一些被編輯到一半的Block恢復成合理的狀態。

三,PipeLine Recovery

我們知道,客戶端和DataNode之間進行數據傳輸是依靠流水線的,客戶端向流水線上發包(Packet),DataNode接收並處理,但是如果在流水線運轉過程中,某個DataNode宕機了,怎么辦呢?這時候就需要PipeLine Recovery機制來恢復我們的流水線,讓流水線恢復到能正常工作的狀態。

關於流水線,請參考 Hadoop架構: 流水線(PipeLine)

我們知道,流水線是由DataNode串聯而成的,就像一條水管,數據(Packets)從一端流進去,依次經過流水線上的各個DataNode,當最后一個DataNode收到數據,將會發出ACK(Acknowledge)給前一個

DataNode,前一個DataNode收到ACK后又會向前一個DataNode發送ACK。回復(ACK)相反地從尾端流回執行寫操作的客戶端(Writer)。

那么,只要是流水線上一個DataNode宕機了,都會導致整個PipeLine的DataStream(數據流動)環節無法正常運轉。就像自行車鏈條,一個關節壞了,整個鏈條就轉不起來。

所以,我們需要PipeLine Recovery機制(流水線恢復),保證DataStream繼續運作。

   流水線恢復按階段不同分為3種:

1.架設流水線階段失敗

2.流水線傳輸數據階段失敗

3.流水線關閉階段失敗

  架設階段失敗:

 分情況:

 1.流水線是用來創建新的Block的客戶端放棄掉(Abandon)新建的Block,重新向NameNode申請一塊Block並且將重新架構流水線。

 2.流水線是用來對已有文件寫入數據的客戶端重新架構流水線,並且把Block的BGS+1

    傳輸數據階段失敗:

 步驟:

   1.客戶端排除掉出錯的DataNode(稱之為BadNode),BadNode會通過斷開與客戶端的TCP連接的方式將自己隔離出流水線,並且盡可能地將已經確認(收到ACK)的數據寫入磁盤,最后關閉文件。

   2.客戶端檢測到流水線上發送回來的ACK不對數,少了某個DataNode,會停止發送Packet

   3.客戶端將重新架設流水線,並且根據 fs.client.block.write.replace-datanode-on-failure.policy/enable 的設置決定是否尋找新的節點代替BadNode,客戶端向NameNode申請新的BGS,這個BGS將在重新架設流水線成功后,成為Replica和Block的BGS。這樣BadNode的Rplica的BGS就和還健在的DataNode,以及NameNode那邊Block的BGS相差1,如果以后BadNode重啟,加入流水線,那么因為Replica的版本(BGS是Replica的版本標識)過老,而被要求刪除(或許能夠恢復,如果客戶端也掛了)

   4.客戶端重新發送數據,從哪里開始發送呢?假如客戶端最后收到ACK的數據Packet是P,那么重新從P后開始發送數據。

   5.DataNode如果接收到4中發來的Packet時,發現自己已經有這部分數據了,就會簡單的把這個Packet發給下游。

 

  關閉階段失敗: 

   步驟:

   1.客戶端嘗試新建流水線,用來告知DataNode應該把Replica給FINALIZE掉

   2.DataNode等待客戶端發送endBlock包,這個包是用來告訴DataNode,Block傳輸完成的,當DataNode收到這個包,將把Replica設置成FINALIZED。

   3.DataNode在關閉網絡連接前,會向客戶端發送endBlock包的確認包

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM