1. 程式人生 > >解讀Raft(四 成員變更)

解讀Raft(四 成員變更)

將成員變更納入到演算法中是Raft易於應用到實踐中的關鍵,相對於Paxos,它給出了明確的變更過程(實踐的基礎,任何現實的系統中都會遇到因為硬體故障等原因引起的節點變更的操作)。

顯然,我們可以通過shutdown叢集,然後變更配置後重啟叢集的方式達到成員變更的目的。但是這種操作會損失系統的可用性,同時會帶來操作失誤引起的風險。支援自動化配置,即配置可以在叢集執行期間進行動態的變更(不影響可用性)顯示是一個非常重要的特性。

Raft成員變更機制

在成員變更時,因為無法做到在同一個時刻使所有的節點從舊配置轉換到新配置,那麼直接從就配置向新配置切換就可能存在一個節點同時滿足新舊配置的“超過半數”原則。

如下圖,原叢集由Server1、Server2、Server3,現在對叢集做變更,增加Server4、Server5。如果採用直接從舊配置到新配置的切換,那麼有一段時間存在兩個不想交的“超過半數的叢集”。

上圖,中在中間位置Server1可以通過自身和Server2的選票成為Leader(滿足舊配置下收到大多數選票的原則);Server3可以通過自身和Server4、Server5的選票成為Leader(滿足新配置線,即叢集有5個節點的情況下的收到大多數選票的原則);此時整個叢集可能在同一任期中出現了兩個Leader,這和協議是違背的。

為了保證安全性,Raft採用了一種兩階段的方式。

第一階段稱為joint consensus,當joint consensus被提交後切換到新的配置下。

joint consensus狀態下:

  • 日誌被提交給新老配置下所有的節點
  • 新舊配置中所有機器都可能稱為Leader
  • 達成一致(選舉和提交)要在兩種配置上獲得超過半數的支援

具體的切換過程如下:

  • Leader收到C-old到C-new的配置變更請求時,建立C-old-new的日誌並開始複製給其他節點(和普通日誌複製沒有區別)
  • Follower以最新的配置做決定(收到C-old-new後就以C-old-new來決定),Leader需要以已經提交的配置來做決定(即只有C-old-new複製到大多數節點後Leader才以這個配置做決定);這個時候處於一個共同決定的過程
  • 之後提交C-new到所有節點,一旦C-new被提交,舊的配置就無所謂了

從上圖可以看出,不存在一個階段C-old和C-new可以同時根據自己的配置做出決定,所以不會出現本文開頭描述的情況。

Review成員變更

如果當前的Leader不在C-new的配置中會怎麼樣(即當前的Leader是一個要被下線的節點)?

在C-old-new的狀態下,Leader依舊可用;在C-new被commit之後Leader實際已經從叢集中脫離,此時可以對Leader節點進行下線操作,而新叢集則會在C-new的配置下重新選舉出一個Leader。

如果在配置分發過程中Leader Crash了會怎麼樣?

這個問題要分為多種情況:1. C-new已經分發到超過半數節點、2. C-new還沒分發到超過半數的節點

情況1:C-new已經分發到超過半數節點

叢集開始重新選舉,此時在C-new的規則下,舊節點(不存在新配置中的節點)不會贏得選舉(因為他們要在C-old-new的情況下決定,但是拿不到C-new的選票),只有拿到C-new的節點可能成為Leader並繼續下發C-new配置,流程恢復。

情況2:C-new還沒分發到超過半數的節點

這種情況下,C-old-new和C-new的節點都可以成為Leader,但是無所謂,因為無論誰成為Leader,都能根據當前的配置繼續完成後續流程(如果是C-new那麼相當與完成了最終的配置,不在C-new的節點會因為沒有心跳資料而失效)

舊節點下線造成的問題:舊節點收不到心跳觸發選舉,傳送請求給C-old-new中的節點,是否會影響叢集正常執行

Raft的處理方式:當節點確信有Leader存在時,不會進行投票(在Leader超時之前收到新的投票請求時不會提升term和投票)。且開始選舉之前等待一個選舉超時時間,這樣在新Leader正常工作的情況下,不會受到舊節點的影響。

舊節點在發起選舉前需要等待一段時間,那麼這段時間新Leader可以傳送心跳,這樣就減少了影響。 對正常流程的影響不大。(Leader失效後要等一段時間,沒有及時觸發,然而本身這裡就有一個判斷失效的時間,好像影響不大;比如原先超時時間是10s,那麼如果設定成5s,原策略下10s超時就是10s後開始選舉,新策略下5s超時就是超時後再等5s再開始選舉,影響就是超時時間變短)

新的伺服器沒有任何資料,加入進來進來怎麼保證系統的可用性(這個時候新日誌沒辦法Commit就沒辦法響應給客戶端)?

新加入的節點需要時間複製資料,在這個過程完成之前,Raft採用以下機制來保證可用性: 新加入節點沒有投票權(Leader複製日誌給他們,但是不將他們考慮在機器數量裡面——即在判斷是否超過半數時不把這些節點考慮在內),直到這些節點的日誌追上其他節點。

歡迎關注公眾號交流:


丞一

丞一

中介軟體技術專家 at 螞蟻金服丞一,目前就職於螞蟻金服,熱衷於研究分散式系統相關的技術;微信公眾號:MessageQueue,歡迎交流;