raft中集群成员变更
文章目錄
- 1. raft集群變更再學習
- 2. 單階段過度的風險分析
- 3. 兩階段過度的完整性分析
- 4. 集群變更時可能存在的其他問題
- 1. 新加入的節點沒有日志
- 2. 集群領導人可能需要下線
- 3. 從```C-old```中移除的機器可能會干擾集群
1. raft集群變更再學習
??最近再次看raft的中文文檔的時候,前面都很順暢,但是到集群變更這塊兒感覺理解的還不是很透徹,于是回過頭看了一下英文原文,又從網上參考了一些前輩大佬的文章。感覺有點思路了,故在此記錄一下。
??在原文上說的是,如果直接從Cold 切換到Cnew的話因為不能做到atomic的原子操作,所以可能會出現兩個leader在同一個term當中并存的情況。但是對于具體的場景說的不夠細致(也有可能是我的思考的還不夠)
這里我嘗試增強一些解釋
2. 單階段過度的風險分析
??論文中說,如果直接從C-old過度到C-new會存在在集群中同時存在兩個leader的風險,下面我們來嘗試分析一下這個過程
??假如運行到第3步,有s1,s4,s5都是C-new, s2,s3為C-old,這個時候s1突然和其他節點發生了短時間的網絡分區,導致集群進行了重新選舉。
??那么在當前集群中就會同時存在兩個leader,而且term是一致的,可能會引起數據混亂。這種應該就是論文中說的從Cold 切換到Cnew的話因為不能做到atomic的原子操作而導致的問題吧。
3. 兩階段過度的完整性分析
??那么raft如何避免這個問題呢,他使用了被稱為共同一致的兩階段提交方法,也就是通過兩次日志的復制來實現從C-old變成新的C-new,英文稱之為joint consensus,這個過程的第一階段復制的cluster config是C-(old,new), 這個時候要求使用cluster config的時候必須在C-old和C-new上都滿足majority才行,在第一個階段提交后才會再指向一個C-new的復制和提交。
我們再來闡述一下這個過程,首先還是一個沒有出錯的過程
??接下來來重點分析一下在這里如果遭遇了異常應該怎么處理,證明不正確有時候很簡單,就像上面的例子,我們只要舉一個不安全的反例就行了,但是要想證明正確則可能比較困難,我們需要仔細考量每一個過程可能出現的異常:
- 同樣的,假如運行到第3步,有s1,s4,s5都是C-(old,new), s2,s3為C-old,這個時候s1突然和其他節點發生了短時間的網絡分區,導致集群進行了重新選舉
- 這個時候假如s2,s3可以通過選舉得到一個leader,假設為s2, 那么s1,s4,s5雖然可以在C-new配置上達成一致,但是無法在C-old上面達成一致(因為s2,s3不可能再給他們投票,每個term只有一次投票機會),所以也就不會出現兩個leader的情況。
- 這個時候如果是s2,s3中的一個成為了leader,那么對應的C-(old,new)會被清除掉(強勢leader的規則決定),s4,s5需要重新發起加入請求,等于重新走這個過程
- 假如s1,s4,s5中的一個稱為了leader,那么就會繼續完成第3步(讓s2,s3中的至少一個復制C-(old,new))接著往下走第4步。
- 在這整個過程中,無論是哪一個服務器當選leader,C-new都不會單獨起作用,這句話非常重要,也就是是他保證了過度的平穩性。
- 假如運行到第4-5步之間,這個時候無論新舊配置對應的集群都復制了C-(old,new)設置。假如這個時候s1為leader, s1為c-new,s2,s3復制了C-(old,new), s4,s5任然為C-old
- 假如這個時候leader s1重啟,這個時候,因為s4,s5發現cluster config中沒有自己,也不會去競選leader,即使競選也會因為日志比較落后而失敗
- 如果s2,s3中的任意一個當選leader,那肯定沒有問題,因為要滿足C-(old,new),這個時候s1肯定沒有機會再獲得大多數的投票了,
- 如果s1當選leader,那么s2,s3不管是否投票給s1,都會因為C-(old,new)中的C-new的設置而不會當選leader,所以這個算是是安全的。
??以上就是我對raft的集群配置變更的一些理解。同樣,為了這篇文章的完整性,補充一下raft論文中提到的實際中面臨的一些情況
4. 集群變更時可能存在的其他問題
1. 新加入的節點沒有日志
??第一個問題是,新的服務器可能初始化沒有存儲任何的日志條目。當這些服務器以這種狀態加入到集群中,那么他們需要一段時間來更新追趕,這時還不能提交新的日志條目。為了避免這種可用性的間隔時間,Raft 在配置更新之前使用了一種額外的階段,在這個階段,新的服務器以沒有投票權身份加入到集群中來(領導人復制日志給他們,但是不考慮他們是大多數)。一旦新的服務器追趕上了集群中的其他機器,重新配置可以像上面描述的一樣處理。
2. 集群領導人可能需要下線
??第二個問題是,集群的領導人可能不是新配置的一員(因為服務器問題可能需要先將這個leader服務停掉)。在這種情況下,領導人就會在提交了 C-new日志之后退位(回到跟隨者狀態)。這意味著有這樣的一段時間,領導人管理著集群,但是不包括他自己;他復制日志但是不把他自己算作是大多數之一。當 C-new被提交時,會發生領導人過渡,因為這時是最早新的配置可以獨立工作的時間點(將總是能夠在 C-new配置下選出新的領導人)。在此之前,可能只能從 C-old中選出領導人。
3. 從C-old中移除的機器可能會干擾集群
??第三個問題是,移除后不在 C-new中的服務器可能會擾亂集群。這些服務器將不會再接收到心跳,所以當選舉超時,他們就會進行新的選舉過程。他們會發送擁有新的任期號的請求投票 RPCs,這樣會導致當前的領導人回退成跟隨者狀態。新的領導人最終會被選出來,但是被移除的服務器將會再次超時,然后這個過程會再次重復,導致整體可用性大幅降低。
??為了避免這個問題,當服務器確認當前領導人存在時,服務器會忽略請求投票 RPCs。特別的,當服務器在當前最小選舉超時時間內收到一個請求投票 RPC,他不會更新當前的任期號或者投出選票。這不會影響正常的選舉,每個服務器在開始一次選舉之前,至少等待一個最小選舉超時時間。然而,這有利于避免被移除的服務器擾亂:如果領導人能夠發送心跳給集群,那么他就不會被更大的任期號廢黜。
參考
raft 中文
raft 英文
總結
以上是生活随笔為你收集整理的raft中集群成员变更的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 分布式系统杂谈
- 下一篇: 算法训练营01-学习总览