High Availability for the HDFS Namenode
Sanjay Radia, Suresh Srinivas
Yahoo! Inc
(本文為namdnoe HA的設計文檔翻譯)
1. 問題闡述
有許多方法可以改善HDFS Namednoe(NN)的可用性,包括減少啟動時間,更新配置而不需要重啟集群,減少升級時間與提供一個手動或自動的NN故障切換等。本文主要關注于NN的故障切換以解決NN的單點故障問題。
有許多方法用以解決NN的失敗,其中包括使用共享存儲,使用虛擬IP與智能客戶端。 可以使用Zookeeper用于領導者選舉,或者其他架構類似Linux HA。 這些不同的解決方法可以共享一些框架部件, 本文的目的是定義這些框架部件并提供一些具體設計,用以建立一個機器故障切換的解決方案,以此提供HDFS Namenode的高可用性并隔離HDFS的服務。
2. 術語
1) Active NN - 為客戶端提供讀寫操作的服務的活動NN
2) Standby NN - 這個NN等待并當Active NN死去的時候成為active
i. BackupNode 在hadoop-0.21中可用于實現Standby的共享存儲文件系統的名字空間。
3) 為了不導致混淆,我們不會使用Primary 或者 Secondary來代表Active和Standby,因為Secondary在老版本中是checkpoing 節點。
4) Hot,Warm, Cold 的故障切換,Standby NN 存儲正在運行的Active的子狀態 。
i. Cold Standby:Standby NN沒有狀態。
ii. Warm Standby:Standby 有部分狀態:
1. 它已加載fsImage和editLog但是沒有收到塊報告;
2. 它已加載fsImage和roolled logs與所有塊報告。
5) Hot Standby: Standby已經有Active的所有狀態,并立刻啟動。
3. 上層應用
1) 計劃停機: 一個hadoop集群經常需要停止以升級軟件或配置,一個4000節點的hadoop集群需要大約兩個小時的時間重啟。
2) 非計劃停機或服務無響應: Namenode服務經常由于硬件,系統,NN進程失敗或NN 進程程序幾分鐘無響應而出現故障, 然而這些有可能出乎意料的影響一些重要的上層應用。
以上兩種情況下,一個warm或hot 故障切換可以減少停機時間, 事實上計劃升級是影響HDFS服務不可用的最大因素, 因為HDFS Namenode 失敗是很少的。(根據Yahoo 和Facebook的經驗)。
4. 不考慮的情況
1) Active-Active NNs -我們的初始設計是一個NN成為Active而另外一個standby(warm 或hot), 可選方案是可以考慮允許Standby提供讀操作。 我們認為Active-Active 需要額外的工作, 也許需要重新設計。
2) 一個名字空間多于兩個NN
3) 大面積的失敗,這通常叫做BCP。
5. 支持的失敗情況
1) 只要單HW失敗(disks,NICs,links等),兩個時不進行處理,但這種情況下保證數據不會損壞。
2) 軟件失敗:例如NN進程失敗,或者NN 進程死鎖。注意系統無法恢復當standby在剛變成Active的時候出現軟件失敗。
3) NN GC是一個棘手的問題,如果一個NN進入GC并且不回復,它不能被認為死。
6. 需求
1) 只有一個NN處于Active
i. 只有Active能處理客戶端的請求并答復。
ii. 只有Active能改變持久化狀態;
iii. 可選: Standby處理讀請求。
2) 第一步支持手動故障切換-一些組織希望使用故障切換僅僅在軟件升級的時候,這是導致hadoop集群不可用的最大原因。、
3) 無法自動回滾,如果舊的Active重啟或變成健康狀態的時候。
4) 數據比可用性更重要
i. 手動或者自動故障切換不應該導致數據損壞
5) 盡量不用特殊硬件
6) HA安裝和失敗管理應該簡單,并得防止數據損壞即使在操作失誤的情況下。
7) 短時間的NN垃圾收集不應該被認為失敗與觸發自動故障切換。
7. 具體用例
1) 單點NN配置,沒有故障切換
2) Active和Standby手動切換
i. Standby可以是cold/warm/hot
3) Active和Standby 自動切換
i. 兩個NN啟動,一個自動成為Active另外一個成為Standby
ii. Active 和Standby 運行著
iii. Active失敗,或者不健康,Standby接替
iv. Active和Standby運行, Active 手動停機
v. Active和Standby運行,Standby失敗,Active繼續
vi. Active運行,Standby停機維修,Active死并無法啟動,Standby啟動并成為Active
vii. 兩個NN啟動,只有一個起來,它成為Active
viii. Active和Standby運行,Active狀態未知,Standby接替。
8. 設計方案
下面我們描述一些設計方案。在許多地方都有一些選擇,例如:是否存儲NN的實時狀態,如何進行領導者選舉(使用zookeeper 或者Linux HA或者其它方法),或者如何實現隔離技術。然而其余的部分很簡單。下面兩個圖表描述使用zookeeper 和Linux HA做共享存儲的整體方針;設計可以擴展到BackupNode。
NN HA with Shared Storage and Zookeeper

NN HA with Shared Storage and Linux HA

1) NN元數據的共享存儲與無共享存儲
Active與Standby既可以共享存儲(例如NFS)或者Active把edits形成流發給Standby(就像0.21里BackupNode的實現)。其中一些考慮如下:
i. 共享存儲成為單點故障,因此需要其高可用。Bookkeeper 是一個比較好的解決方法但是在prime time還未準備好,可以考慮成為長遠的方法。使用bookkeeper ,NN不需要在本地磁盤保持狀態,導致NN結束時‘無狀態’。某些組織由于其他原因在其集群中已經存在HA NFS。
ii. BackupNode更便宜,因為它不需要使用共享服務器。然而其不支持用例的第三條。
iii. BackupNode不需要隔離技術,只要不必解決用例的第三條時。共享存儲需要隔離。然而,如果我們使用Stonith來解決隔離問題,那么就能解決所有隔離需求。
iv. BackupNode不具有對稱性,因此不能接替除非有Active的完整狀態。
v. 當BackupNode停機時,還是依賴于remote存儲以存儲Active的額外狀態,這就轉回到了共享存儲。

2) 并行塊報告給Active和Atandby
我們的設計中需要并行發送塊報告給Active和Standby以保證warm或hot故障切換。塊報告可以直接由datanode發送,也可以通過中間層把塊報告發給Active和Standby。
3) 客戶端在故障切換時重定向
當Active失敗時,客戶端需要重新連接到新的Active,這叫做客戶端故障切換。有多種方法可以實現。
i. 更改DNS的綁定:這不是一個好方法,因為操作系統以及許多庫把DNS緩存著,因此不會立刻做相應的改變。
ii. 智能客戶端:基于服務器的重定向,重試或者重新查找Active。
1. 注意基于服務器的重定向需要注意腦裂,無論服務器是否重定向。這種情況下一個更好的隔離方法是需要共享存儲,因此只有一端可以寫editlog。
2. 是否可以在HTTP或JMX下工作。
3. 故障切換時間將更長,因為在找到新NN的地址前客戶端總是需要與第一個NN(有可能已經死了)交互。
iii. 使用一個負載平衡器來發送客戶端的請求到正確的NN,但這在大規模的環境中(例如:10萬客戶端)是很困難的。
iv. IP故障切換-這在生產環境下經常用到。
1. Namenode服務器使用虛擬IP地址,虛擬IP地址被Active使用。
2. 問題:在跨交換機的環境下是否工作,是否只能在VLAN中使用。
4) 客戶端在NN啟動時超時
NN在某些情況下花很長時間啟動,加載image,應用edits恢復塊位置信息。這有可能導致客戶端超時并認為NN死了。因此,當Active啟動的時候,應該在客戶端的請求中返回“啟動中”以表示客戶端應該等待。這種模式是safemode的特殊例子。
5) 故障切換控制使用獨立于NN進程的故障切換控制器(Watchdog)
我們的方法是使用獨立于NN進程的故障切換控制器進程。這個故障切換控制器與Linux HA的資源管理器非常相似。在基于Linux HA的解決方法中,作為其一部分的RM可以直接使用。而zookeeper ,我們可以自己寫一個,或者配置Linux HA的資源管理器使用zookeeper 。
故障切換控制器執行以下功能:
i. 監控健康的NN,OS和HW,以及其他資源例如網絡連接。
ii. 使用heartbeat以此選舉領導者。(heartbeat發送給zookeeper,使用zookeeper 選舉領導者 )
iii. 在領導選舉中Active被選中。Active故障切換控制器指示其監控的NN從Standby轉換為Active。(注意每個NN啟動的時候都是Standby,只有在接到故障切換控制器的指示后才成為active)
使用獨立的故障切換控制器進程有以下的優點:
i. 把這個功能集成到NN會導致心跳機制患上GC的失敗。
ii. 故障切換控制器應該是寫成緊湊的代碼,從失敗的應用中獨立出來以增加容錯。
iii. 把選舉機制做成插件形式。
6) 隔離(fencing)
在 故障切換的解決方案中,保證只有一個Active實例能更新共享狀態是很重要的。即使有選舉機制,舊的Active有可能被隔離,不可能立刻成為 Standby,有可能繼續共享共享狀態。Fencing是一種阻止舊Active繼續寫共享存儲的方法。Fencing需要Active服務不重試,在 恢復對共享存儲設備的控制時通過fenced設備返回IO錯誤;在這種情況下舊Active應該退出并附帶錯誤信息(成為standby不是很好)。
下面的共享資源可以考慮:
i. 作為NN元數據的共享存儲器:保證只有Active寫更新到edits logs。
ii. Datanode:保證只有一NN進行刪除操做以移動/管理在datanode上的副本。
iii. 客戶端:客戶端不嚴格的需要NN更新的共享狀態,然而客戶端發送更新命令到兩個NN之一。需要保證只有Active NN給客戶端回復。注意如果共享存儲器fencing時,如果非active NN試圖寫將被fenced并且這種情況下不會返回成功給客戶端。
2) 其他故障切換問題
i. 故障切換時恢復租約-具體TBD。
ii. 故障切換時Pipeline恢復
2. 具體設計
1) Fencing
我們已經描述了fencing和需要fenced的共享資源/狀態,以及NN應該在由于fencing寫失敗的時候退出的需求。
2) Fencing 包含NN元數據的共享存儲
在HDFS-1073中, fsImage和EditLogs已經脫離, 因此只有editlog需要fenced. 注意, 啟動一個新的NN總會啟動一個新的editlog. 一個需要防止的事情是防止舊的active 繼續寫舊的editlog并把這個結果告訴客戶端.
i. 使用NFS, fencing的解決方案需要調查.
ii. 使用Bookeeper, 當前正在與bookkeeper團隊討論增加fencing解決方案.
iii. 使用共享磁盤(SCSI 或者 SAN), 共享磁盤提供一個已經解決的 fencing解決方案, 但不適合hadoop環境.
3) Fencing Datanodes
兩個解決方案:
1. 在heartbeat的答復中, NN返回自己狀態: active或standby
如果DN發現狀態更改, 則向ZK詢問誰是active.
如果active由A改為B,然后改為A, DN應該然后能檢測到.
一個更好的解決方案, 故障切換控制器告訴DN, 但是過多的DN難以等待其確認, 因此需要在協議中解決.
2.
每個NN都有一個序列號, 這個序列號在nn狀態更改時傳遞給DN.
DN在運行時保持這個序列號, DN只聽從最后一個從standby轉換到active的NN.
如果一個此前active的NN重新回來(類似GC), DN將拒絕它, 因為其序列號已經過時, 另外一個新NN已經使用新的序列號代替了它.
4) Fencing 客戶端
一個客戶端發送更新命令到兩個NN中的一個, 只有active NN回答給客戶端. 這需要更深入的調查. 注意如果共享存儲已經fenncing了, 那么非active NN試圖寫不會返回成功給客戶端.
5) 使用stonith作為fencing的解決方案.
如果沒有其他好的解決方案時, Stonith (Shoot the other node in the head) 經常被用于fencing解決方案, Stonith往往通過電源操作關閉其它節點.
6) 領導者選舉和故障切換控制器進程
我們已經概括了把控制進程分離出來的好處, 它還有其它優勢. 故障切換控制器進程在Linux HA中叫做資源管理器, zookeeper沒有類似的看門狗進程, 因此建議使用LinuxHA的RM接口:
因為LinuxHA使用Linux HA 資源管理器作為故障切換控制進程.
為ookeeper寫一個故障切換控制器作為測試是否健康, 直接使用Linux HA資源管理器和zookeeper, 這能有效的使用zookeeper 作為領導者選舉器.
7) 故障切換控制器進程操作
i. 心跳, 用于保證active存活, 失去heartbeat時觸發領導者選舉.
如果是zookeeper , 故障切換控制器定期發送心跳給ZK.
LinuxHA, 其資源管理器管理發送Standby心跳的故障切換控制器.
ii. 使用故障切換控制器監控是否健康.
處理NN的狀態(ps命令)
NN簡單的需求(例如GC)
OS檢測
Nic檢測
交換機檢測
iii. 故障切換控制器需要處理一系列命令, 無論是NN從Standby‐to‐Active 還是 Active‐to‐Standby. 這些操作需要配置, 例如Linux HA允許每個其管理的資源配置一系列的命令.
iv. Standby‐to‐Active過程中, 需要以下過程:
Fenced共享存儲和DN(如果沒有其它資源, 可以使用Stonish)
更新共享客戶端地址和/或虛擬IP
告訴NN轉換為active
v. Active‐to‐Standby轉換中, 需要以下過程
更新客戶端地址或放棄虛擬IP
告訴NN變成standby或退出, 如果NN無回應, 則kill之.
8) NN啟動和Active與standby狀態更改
在啟動NN是進入Standby, 只在接到故障切換控制器的命令后才能轉為active.
9) Standby的NN
i. 不向客戶端提供服務
ii. 讀取image并處理edits
iii. 接收BR并處理, 但不回復”刪除”或”復制”命令給DN
10) NN變為Active
當NN變為active時: 結束處理最新的edits; 告訴客戶端它在啟動模式.
問題: 如果NN僅僅是從Active轉換為Standby或重啟.
11) 客戶端重定向
我們已經概括以上兩種可行的方法. TBD
12) 智能客戶端
TBD描述了智能客戶端的方法, 當客戶端連接NN失敗時通過其它服務(如zookeeper ) 尋找active. 需要討論其利弊.
13) IP故障切換方法
生成領域標準方法, 如何工作: TBD
好處: 適合各種協議, HDFS, HTTP, JMX等
挑戰: 虛擬IP跨網段.
14) 共享存儲方法
Standby從共享存儲器讀取edits, 只有過時的寫到當前未滾動的edits, 詳情:TBD
Fencing已經在上文敘述
15) 非共享存儲方法:使用Backup NN
描述BackupNN的工作以及這種方法: TBD
3. 附錄
1) 自動故障回滾
描述問題以及其產生條件
2) 健忘癥
失去已經和客戶端此前的交流過的信息.
3) GC
如何區別NN不回復的時候是否是GC? 需要調查