本指南概述 HDFS Observer NameNode 功能,以及如何在典型的啟用 HA 的叢集中設定/安裝它。如需詳細技術設計概觀,請查看附加至 HDFS-12943 的文件。
在啟用 HA 的 HDFS 叢集中(如需詳細資訊,請查看 HDFSHighAvailabilityWithQJM),只有一個 Active NameNode 和一個或多個 Standby NameNode。Active NameNode 負責處理所有客戶端要求,而 Standby NameNode 只會透過追蹤來自 JournalNodes 的編輯記錄,以及透過接收來自所有 DataNodes 的區塊報告,來保持關於名稱空間的最新資訊,以及區塊位置資訊。這種架構的一個缺點是 Active NameNode 可能會成為單一瓶頸,並因客戶端要求而超載,特別是在繁忙的叢集中。
HDFS Observer NameNode 功能的持續讀取透過引入一種稱為Observer NameNode的新型 NameNode 來解決上述問題。與備用 NameNode 類似,Observer NameNode 會隨時更新自己關於命名空間和區塊位置資訊。此外,它也有能力提供持續讀取,就像 Active NameNode 一樣。由於在一般環境中,讀取要求佔多數,這有助於平衡 NameNode 流量並改善整體傳輸量。
在新架構中,HA 集群可能包含 3 種不同狀態的 NameNode:活動、備用和觀察者。狀態轉換可能發生在活動和備用、備用和觀察者之間,但不會直接發生在活動和觀察者之間。
為確保單一客戶端內的寫入後讀取一致性,在 RPC 標頭中引入了狀態 ID,這是使用 NameNode 內的事務 ID 實作的。當客戶端透過 Active NameNode 執行寫入時,它會使用 NameNode 中的最新事務 ID 來更新其狀態 ID。在執行後續讀取時,客戶端會將此狀態 ID 傳遞給 Observer NameNode,然後 Observer NameNode 會針對自己的事務 ID 進行檢查,並確保自己的事務 ID 已追上要求的狀態 ID,才會提供讀取要求。這可確保單一客戶端「讀取自己的寫入」語意。在「維持客戶端一致性」區段中,會討論在面對頻外通訊時,如何維持多個客戶端之間的一致性。
編輯記錄尾隨對 Observer NameNode 至關重要,因為它會直接影響在 Active NameNode 中套用交易和在 Observer NameNode 中套用交易之間的延遲。引入了稱為「編輯尾隨快速路徑」的新編輯記錄尾隨機制,以大幅減少此延遲。這是建立在現有的進行中編輯記錄尾隨功能之上,並進一步改善,例如使用基於 RPC 的尾隨取代 HTTP、在 JournalNode 上的記憶體快取等。如需更多詳細資訊,請參閱 HDFS-13150 附加的設計文件。
同時也引入了新的用戶端代理提供者。ObserverReadProxyProvider 繼承了現有的 ConfiguredFailoverProxyProvider,應使用它來取代後者,以啟用從 Observer NameNode 進行讀取。當提交用戶端讀取請求時,代理提供者將首先嘗試叢集中可用的每個 Observer NameNode,並且僅在所有前者都失敗時才回退到 Active NameNode。同樣,引入了 ObserverReadProxyProviderWithIPFailover 來取代 IP 故障轉移設置中的 IPFailoverProxyProvider。
如上所述,用戶端「foo」將在每次向 Active NameNode 請求時更新其狀態 ID,其中包括所有寫入操作。任何定向到 Observer NameNode 的請求都將等到 Observer 看到此交易 ID,確保用戶端能夠讀取其自己的所有寫入。但是,如果「foo」向用戶端「bar」發送帶外(即非 HDFS)訊息,告訴它已執行寫入,則「bar」後續讀取可能看不到「foo」最近的寫入。為防止這種不一致行為,已新增一個新的 msync()
或「metadata sync」命令。當在用戶端上呼叫 msync()
時,它將針對 Active NameNode 更新其狀態 ID,這是一個非常輕量級的操作,因此後續讀取保證與 msync()
的點一致。因此,只要「bar」在執行讀取之前呼叫 msync()
,就保證可以看到「foo」所做的寫入。
要使用 msync()
,應用程式不一定需要進行任何程式碼變更。啟動時,客戶端會在對觀察者執行任何讀取作業前自動呼叫 msync()
,這樣在客戶端初始化之前執行的任何寫入作業都將可見。此外,ObserverReadProxyProvider 支援一種可設定的「自動 msync」模式,它會在一些可設定的間隔自動執行 msync()
,以防止客戶端看到超過時間限制的過期資料。這會產生一些開銷,因為每次更新都需要向 Active NameNode 發出 RPC,因此預設會停用。
若要從 Observer NameNode 啟用一致讀取,您需要在 hdfs-site.xml 中新增一些設定
這將導致 NameNode 建立比對內容實例,它會追蹤目前的伺服器狀態 ID。伺服器狀態 ID 將會傳回客戶端。預設會停用,以最佳化觀察者讀取案例的效能。但這對於 Observer NameNode 功能是 必要的。
<property> <name>dfs.namenode.state.context.enabled</name> <value>true</value> </property>
這會透過進行中的編輯記錄啟用快速編輯記錄追蹤,以及其他機制,例如基於 RPC 的編輯記錄擷取、JournalNodes 中的記憶體快取等。預設會停用,但對於 Observer NameNode 功能是 必要的。
<property> <name>dfs.ha.tail-edits.in-progress</name> <value>true</value> </property>
這會決定 Observer NameNode 相對於 Active 的過期程度。如果太大,RPC 時間會增加,因為客戶端要求會在 RPC佇列中等待較長時間,然後 Observer 會追蹤編輯記錄並趕上 Active 的最新狀態。預設值為 1 分鐘。強烈建議將其設定為較低的值。建議在使用較低的值時啟用後退;請參閱下方。
<property> <name>dfs.ha.tail-edits.period</name> <value>0ms</value> </property>
這會決定備用/觀察者在嘗試從 JournalNodes 追蹤編輯記錄並找不到可用編輯記錄時的行為。當編輯記錄追蹤期間非常短,但叢集負載不高時,這是一種常見的情況。沒有這個設定,這種情況會導致備用/觀察者高度使用,因為它會持續嘗試讀取編輯記錄,即使沒有可用編輯記錄。啟用這個設定後,當編輯記錄追蹤嘗試傳回 0 個編輯記錄時,將會執行指數後退。這個設定會指定編輯記錄追蹤嘗試之間等待的最長時間。
<property> <name>dfs.ha.tail-edits.period.backoff-max</name> <value>10s</value> </property>
這是用於儲存 JournalNode 端編輯的記憶體快取大小(以位元組為單位)。快取用於透過基於 RPC 的追蹤提供編輯。這僅在 dfs.ha.tail-edits.in-progress 已開啟時有效。
<property> <name>dfs.journalnode.edit-cache-size.bytes</name> <value>1048576</value> </property>
強烈建議停用此組態。如果啟用,這會將 getBlockLocations
呼叫轉換為寫入呼叫,因為它需要持有寫入鎖定才能更新開啟檔案的時間。因此,要求會在所有觀察者名稱節點上失敗,並最終回退至活動節點。結果會降低 RPC 效能。
<property> <name>dfs.namenode.accesstime.precision</name> <value>0</value> </property>
引進新的 HA 管理命令,以將備用名稱節點轉換為觀察者狀態
haadmin -transitionToObserver
請注意,這只能在備用名稱節點上執行。在活動名稱節點上呼叫此命令時,將擲回例外狀況。
類似地,現有的 transitionToStandby 也可以在觀察者名稱節點上執行,將其轉換為備用狀態。
注意:觀察者名稱節點參與故障轉移的功能尚未實作。因此,如下一節所述,您應該只使用 transitionToObserver 來啟動觀察者。ZKFC 可以開啟觀察者名稱節點,但當名稱節點處於觀察者狀態時,它不會執行任何動作。ZKFC 將在名稱節點轉換為備用狀態後參與活動節點的選舉。
若要啟用觀察者支援,首先您需要一個啟用 HA 的 HDFS 群集,其中名稱節點超過 2 個。然後,您需要將備用名稱節點轉換為觀察者狀態。最低限度的設定是在群集中執行 3 個名稱節點,一個活動節點、一個備用節點和一個觀察者節點。對於大型 HDFS 群集,我們建議執行兩個或更多個觀察者,具體取決於讀取要求和 HA 需求的強度。
請注意,目前 Observer NameNode 在啟用自動故障轉移時,並未完全整合。如果已啟用 dfs.ha.automatic-failover.enabled,在 Observer NameNode 上執行 ZKFC 的唯一好處是,在將 NameNode 轉移到備用狀態後,它將自動加入 Active 選舉。如果不需要此功能,您可以在 Observer NameNode 上停用 ZKFC。此外,您還需要將 forcemanual 旗標新增到 transitionToObserver 指令
haadmin -transitionToObserver -forcemanual
未來將解除此限制。
想要使用 Observer NameNode 進行讀取存取的用戶端,可以在用戶端端的 hdfs-site.xml 組態檔案中,針對代理程式提供者實作指定 ObserverReadProxyProvider 類別
<property> <name>dfs.client.failover.proxy.provider.<nameservice></name> <value>org.apache.hadoop.hdfs.server.namenode.ha.ObserverReadProxyProvider</value> </property>
不想要使用 Observer NameNode 的用戶端,仍可以使用現有的 ConfiguredFailoverProxyProvider,且不應看到任何行為變更。
想要使用「自動 msync」功能的用戶端,應調整下列組態。這將指定一段時間,如果在此時間內用戶端狀態 ID 尚未從 Active NameNode 更新,則會自動執行 msync()
。如果指定為 0,則在每次讀取作業之前都會執行 msync()
。如果這是一個正時間持續時間,則每次要求讀取作業且在該時間內未與 Active 聯繫時,都會執行 msync()
。如果這是一個負值(預設值),則不會執行自動 msync()
。
<property> <name>dfs.client.failover.observer.auto-msync-period.<nameservice></name> <value>500ms</value> </property>