1 背景
在Hadoop 2.0.0之前,NN是HDFS叢集中的單點故障(SPOF)。每一個叢集隻有一個NN,如果這個機器或程序不可用,整個叢集就無法使用。
這主要從如下兩個方面影響了HDFS叢集的可用性:
- 在發生意外事件(如機器崩潰)時,叢集将不可用,直到重新啟動NN。
- 計劃好的叢集運維事件(如NN機器上的軟體或硬體更新)将導緻叢集的視窗停機。
HDFS的高可用性解決了上述問題,通過在同一個叢集中運作2個以上的NN,其中一個作為active, 其它作為standby。這允許在active NN的機器崩潰或程序不可用時快速故障轉移到新的NN,或者在進行計劃維護時,将NN轉移到standby上。
HDFS的高可用,有2種方案:基于共享NFS的HA、基于QJM/Qurom Journal Manager的HA
HDFS的HA機制,主要分為兩塊:中繼資料同步和主備選舉。
- 中繼資料同步依賴于NFS 或 QJM 的共享存儲
- 主備選舉依賴于ZKFC和Zookeeper
為了友善描述,文中針對一些名稱使用縮寫表示
縮寫 | 描述 |
---|---|
NN | NameNode |
ANN | Active NameNode |
SNN | Standby NameNode |
HA | High Availability |
QJM | Qurom Journal Manager |
ZKFC | ZKFailoverController |
SPOF | a single point of failure |
JN | JournalNode |
ZK | zookeeper |
2 HDFS HA
2.1 基于QJM的HA
hadoop2.x之後,Clouera提出了QJM/Qurom Journal Manager的HA方案。
這是一個基于Paxos算法(分布式一緻性算法)實作的HDFS HA方案,主要優勢如下:
- 不需要配置額外的高性能共享存儲,降低了系統複雜度和維護成本。
- 消除SPOF(單點故障)
- 系統魯棒性(Robust)的程度可配置、可擴充。
基本原理: 使用用2N+1台 JournalNode 存儲EditLog,每次寫資料操作有>=N+1傳回成功時即認為該次寫成功,保證資料不會丢失。
HA 架構圖
- 高可用方案中NN有>=2個,隻有一個是Active狀态,表示正在對外提供服務的,是活躍的NN,其它的NN是StandBy狀态,不對外提供服務的,随時準備替換Active NN.
- JournalNode(JN) : 高效的存儲系統,能夠實作資料的超快速寫入與讀取。JN是一個小的檔案系統叢集,節點數需要是2N+1台
- 當Active NN執行任何命名空間修改時,它會持續地将修改記錄記錄到大多數這些JN上。StandBy NN實時讀取JN内部的資料,實作兩個節點的實時中繼資料同步。 配置參數
- dfs.namenode.shared.edits.dir: 配置JournalNodes 位址,由JournalNodes 叢集提供共享的編輯存儲,由Active NN寫入,由Standby NN讀取,以保持與Active NN所做的所有檔案系統更改同步
- dfs.journalnode.edits.dir: JournalNode守護程序存儲本地狀态的路徑。JournalNode機器上的絕對路徑且隻能配置一個路徑。
<property>
<name>dfs.namenode.shared.edits.dir</name>
<value>qjournal://node1.example.com:8485;node2.example.com:8485;node3.example.com:8485/mycluster</value>
</property>
<property>
<name>dfs.journalnode.edits.dir</name>
<value>/path/to/journal/node/local/data</value>
</property>
2.2 基于共享NFS的HA
與QJM的差別是:使用高性能共享存儲存儲HDFS的中繼資料,但隻有Active NN的才能寫,Standby NN隻能讀
配置如下:
- dfs.namenode.shared.edits.dir : 遠端共享編輯目錄的路徑,備用NN使用同一個目錄,以保持與Active NN所做的所有檔案系統更改同步。這個目錄應該以r/w的方式挂載在NN機器上,且需要配置為絕對路徑
<property>
<name>dfs.namenode.shared.edits.dir</name>
<value>file:///mnt/filer1/dfs/ha-name-dir-shared</value>
</property>
3 HDFS HA自動切換
HA自動切換NN, 需要增加了兩個新的元件:ZooKeeper叢集和ZKFailoverController程序(簡稱ZKFC)
- 叢集啟動 >= 2個NN, 每個NN都會有一個ZKFC,每個ZKFC到Zookeeper上lock節點下建立臨時有序的子節點,節點最小的為Active NN, 其它變為standby的ZKFC會監控lock節點(若節點發生變化,表示Active出現異常)
- ZKFC的作用是監視和管理NN的狀态,管理與ZK的會話,并在active NN不可用時,啟動基于ZK的選舉。
3.1 ZK叢集的作用
- 失敗保護——叢集中的每個NN機器在ZooKeeper中維護一個持久的會話。如果機器崩潰,ZooKeeper會話将過期,通知其他NN應該觸發故障轉移。
- NN主動選舉——ZooKeeper提供了一種簡單的機制,專門選舉一個節點為Active。如果目前Active NN崩潰,另一個節點可能會在ZooKeeper中獲得一個特殊的排他鎖,訓示它應該成為下一個Active NN。
- 防腦裂: ZK本身是強一緻和高可用的,可以用它來保證同一時刻隻有一個活動節點
3.2 ZKFC的作用
- 健康檢測: ZKFC使用健康檢查指令定期ping其本地NN。隻要NN以健康狀态及時響應,ZKFC就認為該節點是健康的。如果節點已崩潰、當機或以其他方式進入不正常狀态,運作狀況螢幕将将其标記為不正常狀态,并觸發回調ZKFailoverController進行自動主備切換
- ZK會話管理 : 當本地NN處于健康狀态時,ZKFC在ZooKeeper中保持一個會話打開。如果本地NN是Active,它還持有一個特殊的“鎖”znode。這個鎖使用了ZooKeeper對臨時節點的支援;如果會話逾時,鎖節點将被自動删除。
- 基于ZK的選舉:如果本地NN是健康的,并且ZKFC看到目前沒有其他節點持有鎖znode,它自己将嘗試擷取鎖。如果它成功了,那麼它就“赢得了選舉”,并負責運作故障轉移以使其本地NN處于Active。
3.3 故障轉移過程
- 當Active NN出現異常【崩潰、假死】,Active NN的ZKFC得知異常後斷開與Zookeeper的連接配接,此時Zokeeper上的臨時節點就會消失
- Standby 的ZKFC收到Zokeeper的斷開資訊,通知standby NN, standby NN遠端登入到原始Active NN節點,強行kill NN程序。
- 通知standby ZKFC搶占Zookeeper上的臨時節點,搶占成功,将狀态從standby變為active
- 當原始Active NN重新恢複後,ZKFC到Zookeeper上lock節點下建立臨時有序的子節點, 但因為節點不是最小的,是以作為standby NN.
3.4 觸發HDFS NN自動切換的場景
- Active NN JVM崩潰: Active NN不能及時響應ZKFC的健康檢測指令,HealthMonitor會觸發狀态遷移SERVICE_NOT_RESPONDING, 然後Active NN上的ZKFC會斷開與ZK的連接配接,Standby NN上的ZKFC會獲得Active Lock, 作相應隔離後成為Active NN。
- Active NN JVM當機:這個是JVM沒崩潰,但也無法響應,同崩潰一樣,會觸發自動切換。
- Active NN 機器當機:此時ActiveStandbyElector會失去同ZK的心跳,會話逾時,Standby NN上的ZKFC會通知ZK删除Active NN的活動鎖,作相應隔離後完成主備切換。
- Active NN 健康狀态異常: 此時HealthMonitor會收到一個HealthCheckFailedException,并觸發自動切換。
- Active ZKFC崩潰:雖然ZKFC是一個獨立的程序,但因設計簡單也容易出問題,一旦ZKFC程序挂掉,雖然此時NN是OK的,但系統也認為需要切換,此時Standby NN會發一個請求到Active NN要求Active NN放棄主結點位置,Active NN收到請求後,會觸發完成自動切換。
- ZooKeeper崩潰:如果ZK崩潰了,主備NN上的ZKFC都會感覺斷連,此時主備NN會進入一個中立模式【NeutralMode】,同時不改變主備NN的狀态,繼續發揮作用,隻不過此時,如果ANN也故障了,那叢集無法發揮Failover, 也就不可用了,是以對于此種場景,ZK一般是不允許挂掉到多台,至少要有N/2+1台保持服務才算是安全的。
參考
HDFS High Availability
HDFS High Availability Using the Quorum Journal Manager
Introduction to HDFS High Availability