Hadoop2.0.0以前,NameNode存在單點失敗(single point of failure) (SPOF) 問題。html
出現單點失敗的緣由:node
(1)NameNode所在的機器掛了;apache
(2)NameNode所在的機器須要硬件或者軟件上的更新維護。安全
新的NameNode須要app
(1)將FS Image加載到內存ide
(2)Replay edit logoop
(3)從DataNodes接收到足夠的Block報告從而離開安全模式;ui
才能從新開始服務。spa
在包含大量文件和Blocks的大的集羣中,namenode的冷啓動可能須要30min或更久。操作系統
NameNode會按期將文件系統的命名空間(文件目錄樹、文件/目錄元信息)保存到FS Image中,從而在NameNode由於掉電或者崩潰而宕機時,NameNode重啓動以後能夠從磁盤加載出FS Image文件從新構造命名空間。可是若是實時地將命名空間同步到FS Image中,將會消耗大量的系統資源,形成NameNode運行緩慢。所以,NameNode會先將命名空間的修改操做保存着在Edit Log中,而後按期合併FS Image和Edit Log。Hadoop 2.X以前,由Secondary NameNode進行FS Image和Edit Log的合併。Hadoop 2.X以後,由Standby NameNode進行合併,合併完再發送給Active NameNode。
NameNode HA包含兩個NameNode,在任意一個時刻,只有一個NameNode是的狀態是Active,另外一個是NameNode的狀態是Standby,此外還包含ZooKeeper Failover Controller(ZKFC)、ZooKeeper以及共享編輯日誌(share edit log)。 Active NameNode負責全部客戶端對集羣的操做, Standby NameNode做爲slave,維護狀態信息以便在提供快速的故障轉移。以下圖所示。
(1)集羣啓動後,一個NameNode處於Active的狀態,提供服務,處理客戶端和DataNodes的請求,並把修改寫到edit log,而後將edit log寫到本地和共享編輯日誌(NFS、QJM等)。
共享編輯日誌分兩種:
1:若是是NFS,那麼主、從NameNode訪問NFS的一個目錄或者共享存儲設備,Active Node對namespace的修改記錄到edit log中,而後將edit log存儲到共享目錄中。Standby NameNode將共享目錄中的edit log 寫到本身的namespace
2:若是是QJM,那麼主、從NameNode與一組單獨的稱爲Journal Nodes(JNs)的守護線程進行通訊,Active Node將修改記錄到大多數(> (N / 2) + 1,N是Journal Nodes的數量),Standby NameNode可以從JNs讀到修改並寫到本身的namespace中
(2)另一個NameNode處於Standby狀態,它啓動時加載FS Image文件,Standby NameNode會不斷將讀入的edit log文件與當前的命名空間合併,從而始終保持着一個最新版本的命名空間,因此Standby NameNode秩序按期將本身的命名空間寫入一個新的FS Image文件,並經過HTTP協議將這個FS Image文件傳回Active NameNode便可。
在發生故障轉移時,Standby節點須要確保本身已經從共享編輯日誌讀到了全部的edit log以後,纔會變成Active節點。這保證了namespace狀態的徹底同步。
(3)爲了實現Standby NameNode在Active NameNode失敗以後可以快速提供服務,每一個DataNode須要同時向兩個NameNode發送塊的位置信息和心跳【塊報告(block report)】,由於NameNode啓動最費時的工做就是處理全部DataNodes的塊報告。爲了實現熱備,增長ZKFC和ZooKeeper,經過ZK選擇主節點,Failover Controller經過RPC讓NameNode轉換爲主或從。
(4)當Active NameNode失敗時,Standby NameNode能夠很快地接管,由於在Standby NameNode的內存中有最新的狀態信息(1)最新的edit log(2)最新的block mapping
quorum journal manager(QJM)是HDFS專門的實現,惟一的目的就是提供高可用的edit log,是大多數HDFS的推薦選擇。
QJM的工做過程:QJM運行一組journal nodes,每一個edit必須被寫入到majority的journal nodes中。一般,journal nodes的數量是3(至少是3個),所以每一個edit必須被寫入到至少兩個journal nodes,容許一個journal nodes失敗。【與ZooKeeper類似,可是QJM不是依賴ZooKeeper實現的】
Why Fencing?
slow network or a network partition能夠觸發故障轉移,即便以前的Active NameNode仍然在正常運轉而且認爲它本身仍然是Active NameNode,這時HA就須要確保阻止這樣的NameNode繼續運行。
兩種隔離
(1)經過隔離保證在同一時刻主NameNoel和從NameNode只有一個可以寫 共享編輯日誌
(2)DataNode隔離:對客戶端進行隔離,要確保只有一個NameNode可以響應客戶端的請求
對於HA集羣來講,同一時刻只能有一個Active NameNode,不然namespace的狀態很快就會發散成兩個,形成數據丟失以及其餘不正確的結果,即"split-brain"。爲了防止這種狀況發生,對於共享存儲必須配置隔離(fencing)方法。在故障轉移期間,若是不能斷定以前的Active 節點放棄了他的Active狀態,隔離處理負責切斷切斷以前的Active節點對共享編輯存儲的訪問,這就防止了以前Active節點對namespace的進一步編輯,從而使得新的Active節點可以安全地進行故障轉移。(即一旦主NameNode失敗,那麼共享存儲須要當即進行隔離,確保只有一個NameNode可以命令DataNodes。這樣作以後,還須要對客戶端進行隔離,要確保只有一個NameNode可以響應客戶端的請求。讓訪問從節點的客戶端直接失敗,而後經過若干次的失敗後嘗試鏈接新的NameNode,對客戶端的影響是增長一些重試時間,但對應用來講基本感受不到。)
Why QJM recommended?
QJM在同一個時刻只容許一個NameNode寫edit log;然而,以前的Active NameNode仍有可能爲客戶端的舊的讀請求服務,此時能夠設置SSH fencing命令來殺死NameNode的進程。
因爲NFS不可能在同一個時刻只容許一個NameNode向它寫數據,所以NFS須要更強的fencing方法,包括:
一、revoking the namenode’s access to the shared storage directory (typically by using a vendor-specific NFS command);
二、disabling its network port via a remote management command;
三、STONITH, or 「shoot the other node in the head,」 which uses a specialized power distribution unit to forcibly power down the host machine.
從Active NameNode到Standby NameNode的轉換經過Failover Controller實現。Hadoop的FC的默認實現是基於ZooKeeper的,從而確保只有一個Active NameNode。Failover Controller的做用是監控NameNode、操做系統、硬件的健康狀態,若是出現NameNode的失敗,則進行故障轉移。
NOTE:HA集羣中的Standby NameNode同時爲namespace的狀態執行檢查點(HA上運行Secondary NameNode, CheckpointNode, or BackupNode是錯誤的)
參考:
(1)《Hadoop The Definitive Guide 4th》
(2)http://hadoop.apache.org/docs/r2.7.2/hadoop-project-dist/hadoop-hdfs/HdfsUserGuide.html