解讀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復制日志給他們,但是不將他們考慮在機器數量里面——即在判斷是否超過半數時不把這些節點考慮在內),直到這些節點的日志追上其他節點。

參考資料

論文:https://ramcloud.atlassian.net/wiki/download/attachments/6586375/raft.pdf

翻譯:https://github.com/maemual/raft-zh_cn

動畫演示:http://thesecretlivesofdata.com/raft/

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM