HDFS 09 - HDFS NameNode 的高可用機制


1 - 為什么要高可用

在 Hadoop 中,NameNode 扮演着至關重要的角色 —— 整個 HDFS 文件系統的元數據信息都由 NameNode 管理,一旦 NameNode 進程出現異常,或者維護 NameNode 所在節點的時候,都會導致 HDFS 集群不可用。

所以 NameNode 的可用性直接決定了 Hadoop 集群的可用性。

2 - NameNode 的高可用發展史

在 Hadoop 2.0 以前,每個 HDFS 集群只有一個 NameNode,一旦這個節點不可用,則整個 HDFS 集群將處於不可用狀態 —— 即,HDFS 2.0 以前,NameNode 存在單點故障風險。

與典型的 HA(High Availability,高可用)方案一樣(參考:常見的六種容錯機制),HDFS 2.0 開始支持的 HA,就是 在 HDFS 集群中同時運行兩個 NameNode

一個處於 Active(活躍)狀態:負責集群中所有客戶端的操作(修改命名空間、刪除備份數據塊等操作);

另一個處於 Standby(備份)狀態:作為從服務器,和 Active NameNode 有相同的命名空間和元數據。

當 Active NameNode 停止服務時,Standby NameNode 能夠快速完成故障切換,以保證 HDFS 集群服務不受影響。

3 - HDFS 的高可用架構

看圖:

問題來了:Standby NemeNode 是如何做到故障切換的?或者說,它是怎樣做到和 Active NameNode 的數據保持一致的?

3.1 Standby 和 Active 的命名空間保持一致

它們存儲着一樣的元數據,可以把集群恢復到系統奔潰時的狀態 —— 這是實現自動故障切換的基礎。

為了使備份節點與活動節點的數據保持同步,這兩個節點都要和一些獨立運行的節點通信,HDFS 中把這樣的節點稱為 JournalNode。

1)第一關系鏈的一致性,即 Active NameNode 和 Standby NameNode 的命名空間狀態的一致性:

a)Active NameNode 會定期地把 修改命名空間或刪除備份數據塊等操作 記錄到 EditLog,同時寫到 JN 的 多數節點 中。

b)Standby NameNode 會一直監聽 JN 上 EditLog 的變化,如果 EditLog 有改動,Standby NameNode 就會讀取 EditLog 並與當前的命名空間合並。

c)Active NameNode 出現故障時,Standby NameNode 會保證已經從 JN 上讀取了所有 EditLog 並與命名空間合並,然后才會從 Standby 切換為 Active。

2)第二關系鏈的一致性,即數據塊的存儲信息的一致性:

為了使故障切換能夠盡快成功,就要保證 Standby NameNode 也 實時保存了數據塊的存儲信息,HDFS 中是這樣做的:

DataNode 會同時向兩個 NameNode 發送心跳以及數據塊的存儲信息。

這樣一來,發生故障切換時,Standby NameNode 就可以直接切換到 Active 狀態(它和舊 Active 節點的元數據完全一致),而不需要等待所有的 DataNode 匯報全量數據塊信息 —— 這也是熱備功能。

需要注意:Standby NameNode 只會更新數據塊的存儲信息,並不會向 DataNode 發送復制或刪除數據塊的指令,這些指令只能由 Active NameNode 發送。

3.2 同一時刻只有一個 Active NameNode

如果兩個 NameNode 都是活躍狀態,那么這個集群就會被分成2個小集群,它們都認為自己是唯一活動的集群。這就是著名的“腦裂”現象。

腦裂的 HDFS 集群很可能造成數據錯亂、丟失數據塊,還可能向 DataNode 下發錯誤的指令,這些錯誤都很難恢復。

所以,高可用的 HDFS 集群中,Active NameNode 同一時刻只能有一個。

4 - HDFS 高可用的實現原理

這里主要介紹通過隔離(Fencing)Quorum Journal Manager(QJM)共享存儲 實現的 HDFS 高可用。

4.1 隔離(Fencing)- 預防腦裂

預防腦裂的常見方案就是 Fencing(隔離),思路是把舊的 Active NameNode 隔離起來,使它不能對外提供服務,保證集群在任何時候都只有一個 Active NameNode。

HDFS 提供了 3 個級別的隔離(Fencing):

1)共享存儲隔離:同一時間只允許一個 NameNode 向 JournalNode 寫入 EditLog 數據。

2)客戶端隔離:同一時間只允許一個 NameNode 響應客戶端的請求。

3)DataNode 隔離:同一時間只允許一個 NameNode 向 DataNode 下發命名空間相關的命令,例如刪除、復制數據塊等。

4.2 Qurom Journal Manager 共享存儲

在 HDFS 的 HA 架構中還有一個非常重要的部分:Active NameNode 和 Standby NameNode 之間如何共享 EditLog 文件。

思路是:Active NameNode 將日志文件寫到共享存儲上,Standby NameNode 實時地從共享存儲讀取 EditLog 文件,然后合並到 Standby NameNode 的命名空間中。一旦 Active NameNode 發生錯誤,Standby NameNode 就可以立即切換到 Active 狀態。

Hadoop 2.0.3 版本開始,社區接收了由 Cloudera 公司提供基於 Qurom Journal Manager(QJM)共享存儲的高可用方案,來解決 HA 架構中元數據的共享存儲問題:

http://hadoop.apache.org/docs/r2.4.1/hadoop-project-dist/hadoop-hdfs/HDFSHighAvailabilityWithQJM.html

QJM 基於 Paxos 算法實現,基本原理是:HDFS 集群中有 2n+1 台 JournalNode,EditLog 保存在 JN 的本地磁盤上;

每個 JournalNode 都允許 NmaeNode 通過它的 RPC 接口讀寫 EditLog 文件;

當 NmaeNode 需要寫 EditLog 文件時,它會通過 QJM 向集群中所有的 JournalNode 並行發送寫 EditLog 文件的請求;

每次寫數據操作只要有超過一半(>=n+1)的 JournalNode 返回成功,就認為這次寫操作成功了。

由此我們可以知道,這個 QJM 必須也是高可用的,否則 HDFS 的高可用就無法保障。

QJM 實現 HA 的主要好處:

  • 不存在單點故障問題;
  • 不需要配置額外的共享存儲,降低了復雜度和維護成本;
  • 不需要單獨配置 Fencing 實現(見文末#5.1節),因為 QJM 本身就內置了 Fencing 的功能;
  • 系統的魯棒性程度是可配置的( QJM 基於 Paxos 算法,配置 2n+1 台 JournalNode,最多能容忍 n 台機器同時掛掉);
  • QJM 中存儲日志的 JournalNode 不會因為其中一台的延遲而影響整體的延遲,而且也不會因為 JournalNode 的數量增多而影響性能(因為 NameNode 向 JournalNode 發送日志是並行的)。

關於 QJM 的具體工作原理,后面有機會了專門講講。

5 - 其他補充

5.1 基於 NFS(共享存儲)的高可用

2010年 Facebook 提出了基於 NFS(共享存儲)的高可用方案,又可稱為 AvatarNode 架構。

但由於需要額外保證 NFS 的高可用,以及額外實現鼓掌切換(Failover),並且共享存儲的價格較為昂貴,與 HDFS 構建在“inexpensive commodity hardware”設計初衷不相符合,所以此方案被 QJM 所代替。

QJM 自 Hadoop 2.0 開始,就一直是 Hadoop 社區默認 HDFS HA 方案。

5.2 QJM 的 Fencing 方案

QJM 的 Fencing 只能讓原來的 Active NN 失去對 JournalNode 的寫權限,但是原來的 Active NN 還是可以響應客戶端的請求,對 DataNode 進行讀操作。

對客戶端和 DataNode 的隔離是通過配置 dfs.ha.fencing.methods 實現的,Hadoop 公共庫中有兩種 Fencing 實現:

shell:即執行一個用戶事先定義的 shell 命令或腳本來完成隔離。

sshfence:ssh 到原 Active NN 上,使用 fuser 結束進程(通過 TCP 端口號定位進程 pid,比 jps 命令更准確)。

5.3 - HDFS 的高可用組件

5.3.1 ZKFailoverController

是基於 ZooKeeper 的故障轉移控制器,它負責控制 NameNode 的主備切換,ZKFailoverController 會監測 NameNode 的健康狀態,當發現 Active NameNode 出現異常時會通過 ZooKeeper 進行新的選舉,完成 Active 和 Standby 狀態的切換。

5.3.2 HealthMonitor

周期性調用 NameNode 的 HAServiceProtocol RPC 接口(monitorHealth 和 getServiceStatus),監控 NameNode 的健康狀態並向 ZKFailoverController 反饋。

5.3.3 ActiveStandbyElector

接收 ZKFailoverController 的選舉請求,通過 ZooKeeper 自動完成主備選舉,選舉完成后回調 ZKFailoverController 的主備切換方法對 NameNode 進行 Active 和 Standby 狀態的切換。

參考資料

https://hadoopdoc.com/hdfs/hdfs-namenode-ha

https://blog.csdn.net/u012736748/article/details/79534019


版權聲明

作者:瘦風(https://healchow.com)

出處:博客園-瘦風的南牆(https://www.cnblogs.com/shoufeng)

感謝閱讀,公眾號 「瘦風的南牆」 ,手機端閱讀更佳,還有其他福利和心得輸出,歡迎掃碼關注🤝

本文版權歸博主所有,歡迎轉載,但 [必須在頁面明顯位置標明原文鏈接],否則博主保留追究相關人士法律責任的權利。


免責聲明!

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



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