日本综合一区二区|亚洲中文天堂综合|日韩欧美自拍一区|男女精品天堂一区|欧美自拍第6页亚洲成人精品一区|亚洲黄色天堂一区二区成人|超碰91偷拍第一页|日韩av夜夜嗨中文字幕|久久蜜综合视频官网|精美人妻一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
JointConsensus兩階段成員變更的單步實現(xiàn)

[[428425]]

一 引言

分布式系統(tǒng)運行過程中節(jié)點經(jīng)常會出現(xiàn)故障,需要支持節(jié)點的動態(tài)增加、刪除和替換。

成員變更是分布式系統(tǒng)繞不開的話題,特別是在一致性系統(tǒng)中,對于提升運維能力和服務(wù)可用性都有很大的幫助。

Raft提出的兩階段成員變更Joint Consensus是業(yè)界主流的成員變更方法,極大的推動了成員變更的工程應(yīng)用。但Joint Consensus成員變更采用兩階段,一次變更需要提議兩條日志, 在一些系統(tǒng)中直接使用時有些不便。雖然Raft也提出了單步成員變更方法,但單步成員變更方法一次只能增加或減少一個成員,限制較大,并且容易踩坑,一般不推薦使用。

那么很自然的想到,Joint Consensus成員變更能否只使用單步實現(xiàn)呢?本文對這個問題進行了深入探討。

二 成員變更

我們先來回顧下一致性協(xié)議中的成員變更問題。成員變更是在集群運行過程中改變運行一致性協(xié)議的節(jié)點,如增加、減少節(jié)點、節(jié)點替換等。成員變更過程不能影響系統(tǒng)的可用性。

成員變更也是一個一致性問題,即所有節(jié)點對成員配置達成一致。但是成員變更又有其特殊性,因為在成員變更的過程中,參與投票的成員會發(fā)生變化。

圖1 成員變更的某一時刻Cold和Cnew中同時存在兩個不相交的多數(shù)派

如果將成員變更當(dāng)成一般的一致性問題,成員變更過程中,各節(jié)點從舊成員配置Cold切換到新成員配置Cnew的時刻可能有差異,可能在某一時刻Cold和Cnew中同時存在兩個不相交的多數(shù)派,形成雙Quorum,破壞一致性。

為了解決這個問題,Raft提出了兩階段的成員變更方法Joint Consensus。

1 Joint Consensus成員變更

Joint Consensus成員變更為了避免雙Quorum問題,引入一個聯(lián)合成員配置Cold,new作為過渡配置, Cold,new是Cold和Cnew的組合。Cold與Cold,new的Quorum有交集,Cold,new與Cnew的Quorum也有交集。成員變更先從Cold切換到Cold,new,待Cold,new提交后,再切換到Cnew,保證Cold與Cnew不同時使用,因而不會形成雙Quorum,保障安全性。

圖2 Cold與Cold, new與Cnew三者的Quorum集合之間的關(guān)系

Joint Consensus使用兩條日志完成成員變更過程。Leader收到成員變更請求后,先向Cold和Cnew同步一條Cold,new日志,此后所有日志都需要Cold和Cnew兩個多數(shù)派的確認。Cold,new日志在Cold和Cnew都達成多數(shù)派之后才能提交,此后Leader再向Cold和Cnew同步一條只包含Cnew的日志,此后日志只需要Cnew的多數(shù)派確認。Cnew日志只需要在Cnew達成多數(shù)派即可提交,此時成員變更完成,不在Cnew中的成員自動下線。

 圖3 Joint Consensus成員變更過程

成員變更過程中如果發(fā)生Failover,老Leader宕機,Cold,new中任意節(jié)點都可能成為新Leader,如果新Leader上沒有Cold,new日志,則繼續(xù)使用Cold,F(xiàn)ollower上如果有Cold,new日志會被新Leader截斷,回退到Cold,成員變更失敗;如果新Leader上有Cold,new日志,則繼續(xù)將未完成的成員變更流程走完。

2 單步成員變更

Joint Consensus成員變更之所以需要兩個階段,是因為對Cold與Cnew的關(guān)系沒有做任何假設(shè),為了避免Cold和Cnew各自形成不相交的多數(shù)派而形成雙Quorum,才引入了兩階段方案。

如果增強成員變更的限制,假設(shè)Cold與Cnew的Quorum交集不為空,Cold與Cnew就無法形成雙Quorum,則成員變更就可以簡化為一階段。

實現(xiàn)單步的成員變更,關(guān)鍵在于限制Cold與Cnew,使Cold與Cnew的Quorum交集不為空。那么怎么樣限制Cold與Cnew,才能使Cold與Cnew的Quorum交集不為空呢?方法就是每次成員變更只允許增加或刪除一個成員。

圖4 增加或刪除一個成員時Cold與Cnew的Quorum

增加或刪除一個成員時的情形,如圖4所示,可以從數(shù)學(xué)上嚴格證明,只要每次只允許增加或刪除一個成員,Cold與Cnew不可能形成兩個不相交的Quorum。因此只要每次只增加或刪除一個成員,從Cold可直接切換到Cnew,無需過渡成員配置,實現(xiàn)單步成員變更。

單步成員變更一次只能變更一個成員,如果需要變更多個成員,如實現(xiàn)替換成員等,可以通過執(zhí)行多次單步成員變更來實現(xiàn)。

單步成員變更理論雖然簡單,但卻埋了很多坑,實際用起來并不是那么簡單。先前的文章Raft成員變更的工程實踐中有詳細介紹。

三 兩階段成員變更的單步實現(xiàn)

Joint Consensus成員變更雖然通用但是采用兩階段,一次變更需要提交兩條日志,單步成員變更雖然只需要提交一條日志,但是限制較大,一次只能變更一個成員。兩者的優(yōu)勢能否結(jié)合呢?Joint Consensus成員變更能否只用單步實現(xiàn)呢?

Joint Consensus成員變更過程中,Cold,new日志的提交已經(jīng)讓各節(jié)點對Cnew配置達成了一致,那么Cnew日志有什么作用呢?能否在Cold,new日志提交后就從Cold,new配置切換到Cnew配置呢?這樣是不是就可以不需要Cnew日志,變成單步實現(xiàn)了呢?

考慮Joint Consensus成員變更中Cnew日志的作用,Cnew日志在Cold,new日志提交之后發(fā)起提議,節(jié)點收到并持久化Cnew日志后從Cold,new配置切換到Cnew配置,不在Cnew配置中的成員在Cnew日志提交后下線。根據(jù)這個過程,可以總結(jié)出Cnew日志的作用:

通知節(jié)點在收到并持久化Cnew日志后從Cold,new配置切換到Cnew配置。

通知不在Cnew配置中的節(jié)點在Cnew日志提交后下線。

成員變更過程中發(fā)生Failover后,本地有Cnew日志的節(jié)點具有優(yōu)先選舉權(quán)。

如果能不使用Cnew日志同時又完成Cnew日志的工作,不就可以用單步實現(xiàn)兩階段的Joint Consensus成員變更嗎?事實上已經(jīng)有系統(tǒng)探索過這條路。

1 ZooKeeper成員變更

ZooKeeper從3.5.0版本開始在Zab的基礎(chǔ)上支持了成員變更。ZooKeeper具有Primary Order特性,而使用兩條日志的Joint Consensus成員變更無法保證Primary Order特性,為了既滿足成員變更的通用性,又不喪失Primary Order特性,ZooKeeper在論文《Dynamic Reconfiguration of Primary/Backup Clusters》中提出了自己的成員變更方法,并在ZooKeeper中應(yīng)用了此方法,比Raft的提出還早。

如圖5是ZooKeeper成員變更協(xié)議,圖中舊成員配置用S表示,新成員配置用S‘表示,P為Leader節(jié)點,圖5展示了將B1和B2節(jié)點替換成B3和B4節(jié)點的過程:

圖5 ZooKeeper成員變更協(xié)議

  • 為了讓新節(jié)點追上最新數(shù)據(jù),新成員配置S’中的新節(jié)點B3、B4先連接到當(dāng)前的主節(jié)點P,P會向它們傳輸自己當(dāng)前的狀態(tài)作為他們的初始狀態(tài)。在Zab協(xié)議中當(dāng)備節(jié)點連接上主節(jié)點時這樣的狀態(tài)傳輸就會自動發(fā)生,并且會繼續(xù)從主節(jié)點P接收所有后續(xù)的操作日志(例如圖中的Op1和Op2),這個過程中節(jié)點B3、B4不參與投票。
  • 主節(jié)點P向連接到它的所有備節(jié)點(S U S‘)發(fā)送成員變更日志COP,COP日志中攜帶舊成員配置S和新成員配置S‘,并等待舊成員配置S中的節(jié)點確認。一旦S中的多數(shù)派確認了COP日志,就對S’達成了共識。
  • 在COP日志之前的日志只需要舊成員配置S中的多數(shù)派確認,可以在舊成員配置和新成員配置(S U S‘)中提交;在COP命令之后且在S’的激活消息ACTIVATE之前的日志需要新舊成員配置(S U S‘)兩個多數(shù)派確認,并且只能在S’中提交;在S’的激活消息ACTIVATE后的日志,只需要在S‘中確認和提交。
  • 主節(jié)點P等待COP日志以及S'中COP之前的日志的確認。
  • 一旦新舊成員配置(S U S1)兩個多數(shù)派都確認了COP日志,主節(jié)點P就提交COP日志,并廣播一條激活消息ACTIVATE來激活新成員配置S’從而完成成員變更。與日志同步消息類似,ACTIVATE消息包含主節(jié)點P的Epoch,攜帶過時的Epoch的ACTIVATE消息將被忽略。

成員變更過程中如果發(fā)生Failover,可能出現(xiàn)下面幾種情況:

如果在COP日志發(fā)送之前Failover,那么成員變更失敗,在舊成員配置中重新選主后繼續(xù)工作;

如果在COP日志發(fā)送之后并且在ACTIVATE之前Failover,新舊成員配置中任意節(jié)點都可能成為新Leader,如果新Leader上沒有COP日志,則成員變更失敗;如果新Leader上有COP日志,則繼續(xù)將未完成的成員變更流程走完。

如果在ACTIVATE后Failover,成員變更已經(jīng)完成,但還無法保證新Leader一定在新成員配置中,此時不在新成員配置中的節(jié)點還不能下線。因此在發(fā)送ACTIVATE消息后還需要在新成員配置中提交一條no-op日志,no-op日志提交后可保證新Leader一定在新成員配置中,不在新成員配置中的節(jié)點可以安全下線。

ZooKeeper利用異步的Commit消息,也即ACTIVATE消息來通知節(jié)點從新舊成員配置切換到新成員配置。使用異步的no-op日志讓不在新成員配置中的節(jié)點安全下線。ZooKeeper的ACTIVATE消息和異步的no-op日志起到了Joint Consensus成員變更中Cnew日志的作用。

2 改進的單步實現(xiàn)

ZooKeeper成員變更協(xié)議不如Joint Consensus成員變更那么簡潔,Joint Consensus成員變更通過兩階段可以利用協(xié)議本身而不需要做過多的限制來保證成員變更的安全性。那么ZooKeeper成員變更協(xié)議是否可以改進呢?

ZooKeeper成員變更協(xié)議中異步的ACTIVATE消息和no-op日志其實就是為了完成Joint Consensus成員變更中Cnew日志的作用,明白了這一點后那么也可以將Joint Consensus成員變更的Cnew日志改為異步的,在Cold,new日志提交后就認為成員變更完成,然后異步的提交Cnew日志。之所以可以將Cnew日志改為異步的,在Cold,new日志提交后就認為成員變更完成,是因為Cold,new日志一旦提交,各節(jié)點已經(jīng)對新成員配置達成了一致,再也不會回退到舊成員配置了,剩下的過程最終一定會執(zhí)行完成,Cnew日志最終一定會提交。

還有一種改進方法是繼續(xù)保留ACTIVATE消息,但不使用no-op日志,那么怎么樣保證切換到新成員配置的節(jié)點具有優(yōu)先選舉權(quán)呢?根據(jù)選舉的安全性,具有最新日志的節(jié)點具有優(yōu)先選舉權(quán),那么可以在選舉的時候攜帶節(jié)點當(dāng)前的成員配置,在日志一樣新的情況下,優(yōu)先給已經(jīng)切換到新成員配置的節(jié)點投票,即可保證切換到新成員配置的節(jié)點具有優(yōu)先選舉權(quán)。新成員配置中的大多數(shù)節(jié)點切換到新成員配置后,不在新成員配置中的節(jié)點可以安全下線。

四 總結(jié)

Joint Consensus成員變更的提出極大的推動了成員變更的工程應(yīng)用,其簡潔優(yōu)美并且通用,但是采用兩階段,一次變更需要提交兩條日志。本文探討了兩階段的Joint Consensus成員變更的單步實現(xiàn)方法,并做了一些改進,為成員變更的工程應(yīng)用提供了更多的選擇。

五 思考

為什么Cold,new日志提交后,Cnew日志最終一定會提交?

使用ACTIVATE消息讓節(jié)點切換到新成員配置后,如果節(jié)點重啟,如何保證繼續(xù)使用新成員配置?

兩階段成員變更的單步實現(xiàn)還有沒有其它實現(xiàn)方法?


當(dāng)前名稱:JointConsensus兩階段成員變更的單步實現(xiàn)
網(wǎng)頁鏈接:http://www.dlmjj.cn/article/ccsooph.html