HDFS中NameNode 單點失敗的改進案例介紹

在Hadoop的使用中,NameNode的單點失敗問題一直困擾着框架的使用者。這一節我們提出了一種利用ZooKeeper對NameNode進行冗餘備份協同工作方案,避免了NameNode單點失敗造成的服務不可用與文件丟失問題。

NameNode是整個HDFS的核心,HDFS所有的操作均需由NameNode參與,並且NameNode負責維護整個分佈式文件系統中所有文件的元信息以及目錄信息。如果NameNode出現了失敗,那麼HDFS中所有文件信息將全部丟失。雖然HDFS針對每一個文件都可以根據配置進行多份數據備份,但是NameNode卻只有一個。這使得NameNode成爲了HDFS中的薄弱點,如果NameNode發生單點失敗將導致整個HDFS系統的失敗。

圖1-9NameNode架構圖

HDFS中使用SecondaryNameNode解決NameNode失敗的問題。SecondaryNameNode並不是NameNode的冗餘備份,而是單獨的一個參與者,負責對NameNode中文件元信息以及文件結構定期快照。SecondaryNameNode定期從NameNode上下載鏡像和日誌進行合併,稱爲一次checkpoint,將得到的新的鏡像文件上傳到NameNode替換原來的鏡像文件,使得NameNode上的鏡像文件保持最新。當NameNode出現失敗時,可以從SecondaryNameNode所在的機器拷貝之前的快照,然後重啓NameNode,此時NameNode會導入快照中保存的文件信息,重建文件系統。

SecondaryNameNode方案存在以下幾個問題:

1.必須通過人工的方式尋找並拷貝SecondaryNameNode中保存的快照文件,手工重啓NameNode,無法自動化完成。

2.在NameNode失敗期間,任何人都無法面對HDFS中的文件進行任何形式的訪問,系統失敗的時間取決於人工恢復NameNode的時間。

3.NameNode是以文件鏡像(fsimage)和操作日誌(edit)方式存儲HDFS中文件元信息和目錄結構的,其中edit是實時日誌信息,每過一段時間(默認1小時)或當操作日誌文件大小增加到一定規模時(默認64MB)由SecondaryNameNode負責將edit合併到文件鏡像中並備份。如果NameNode發生失敗而由SecondaryNameNode中快照恢復的話,會導致尚處在操作日誌中未被合併的文件操作信息完全丟失,從而導致文件丟失。

爲了解決NameNode單點失敗造成的問題,改進的HDFS系統中可配置多個NameNode,每個NameNode與所有的DataNode均有聯繫,且向ZooKeeper註冊自己的存在(在特定的ZNode下創建臨時性ZNode,並將自身信息保存在對應ZNode中)。與此同時,架構中加入一個角色Dispatcher,負責將讀、寫請求傳遞給活躍的NameNode執行、處理多個NameNode的同步以及互斥問題,並根據ZooKeeper提供的信息監控NameNode的健康情況以確保當某個NameNode發生失敗後將其從“活躍的”NameNode列表中去除。


圖1-10改進後的HDFS系統架構圖

改進後的HDFS系統包括讀流程和寫流程兩個部分,其中讀流程如下:

1.用戶發起一個讀文件請求;

2.Dispatcher收到讀請求,檢查ZooKeeper中的InWriting列表,如果在InWriting列表中則等待,否則將讀請求加入InReading列表中。

3.從ZooKeeper中尋找活躍的NameNode,將此讀請求轉發給對應的NameNode並記錄。

4.Namenode收到讀請求後處理,將處理結果交由Dispatcher並反饋給用戶。Dispatcher從InReading列表中刪除對應請求。

5.如果Namenode長時間未響應或者讀請求失敗,由Dispatcher尋找另外的Namenode,轉第3步。

寫文件流的流程如下:

1.用戶發起一個寫文件請求。

2.Dispactcher收到寫請求,檢查ZooKeeper中的InWriting和InReading列表,如果在列表中則等待,否則將寫請求加入InWriting列表中。

3.從ZooKeeper中尋找活躍的NameNode,將此寫請邱轉發給對應的NameNode並記錄。

4.NameNode收到寫請求後處理,如果寫操作成功,則通知Dispatcher。Dispatcher告知其他NameNode此次寫操作細節,其他NameNode做對應更新。

5.所有NameNode均更新完畢後,Dispatcher從InWriting中移除對應請求,並返回給用戶。

6.如果NameNode長時間未響應或者寫請求失敗,由Dispatcher尋找另外的NameNode,轉第3步。

當某一個NameNode失敗時,ZooKeeper中對應的臨時性ZNode會自動消失,而Dispatcher在得知此事件後,可以將其從活躍NameNode中去除,對於已經分配給此NameNode且尚未處理完成的讀寫請求可以重新分配。而對於後續的讀寫請求,Dispatcher則交給仍然活躍的NameNode進行處理,對於用戶來說是透明的。

改進後的HDFS系統中Dispatcher變成了單點,依舊存在失敗的風險。但Dispatcher失敗的可能性與危害都遠遠小於NameNode失敗。原因有以下幾點:

1.爲了維護HDFS系統中的文件源信息以及目錄結構,NameNode需要將所有數據全部載入內存,這使得當文件系統足夠龐大時NameNode需要消耗很多的內存,這無疑增加了失敗的可能性。而Dispatcher的任務相對較輕,僅僅是作爲一箇中轉站轉發讀寫請求,失敗的可能性較小。

2.Dispatcher自身不保存任何數據。所有的數據完全交由ZooKeeper存儲,而ZooKeeper自身的特性保證了其很難出現失敗。即使Dispatcher失敗,也可以重新啓動並根據ZooKeeper中記錄的信息完全恢復。

3.作爲一個成熟的分佈式文件系統,對文件安全性與完整性的保證是十分重要的。如果是單NameNode,不管SecondaryNameNode備份間隔如何縮短,在上一次備份到系統失敗這段時間內的文件操作便會全部丟失,這有可能給系統的使用者帶來不可挽回的損失。而改進後的系統不存在這個問題,如果一個修改操作成功,則會被保存在所有NameNode上,丟失文件的機會很小。

所以,相對於只有一個NameNode的HDFS系統,改進後的HDFS系統具有很強的安全性。當一個NameNode失敗後,使用活躍的NameNode中拷貝過來的fsimage和edit文件作爲恢復用途。在添加或恢復一個NameNode之前,先向ZooKeeper註冊一個“備用的”NameNode節點,而Dispatcher在發現有此類節點時則將之後所有的成功寫請求保存在ZooKeeper上。當新添加的NameNode使用fsimage和edit文件恢復完成後,在Dispatcher再將記錄的寫請求按照順序發送給此NameNode,此NameNode根據這一信息同步文件元信息及目錄結構。當新的NameNode同步完成時,刪除ZooKeeper中備用NameNode節點,添加正式的NameNode臨時節點。此事Dispatcher便可得知系統中新NameNode的存在並使用。



歡迎關注麥克叔叔每晚十點說,有興趣的朋友可關注公衆號,讓我們一起交流,一起學習。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章