理解Paxos演算法的推導過程

2021-08-05 20:30:12 字數 4526 閱讀 3142

paxos作為分布式系統的基石,一直都是cs領域的熱門話題,paxos號稱是最難理解的演算法。最近幾天一直在看paxos相關資料,發現paxos演算法執行過程很簡單,但如何推導出paxos演算法確實令人費解。網上有大量關於paxos的基本概念、演算法描述、推導過程等文章,所以關於paxos的基本概念就不贅述了,但很多文章都沒有說清楚推導過程中一些容易讓人疑惑的問題(例如為什麼提案要被設計為編號+value?value被選定的條件為什麼是半數以上而不是其他?等等),本文將試圖描述清楚paxos的推導過程,並解答一些常見的疑問。

先描述演算法流程,paxos演算法分為兩個階段,具體如下:

階段一

(a) proposer選擇乙個提案編號n,然後向半數以上的acceptor傳送編號為n的prepare請求。

(b) 如果乙個acceptor收到乙個編號為n的prepare請求,且n大於該acceptor已經響應過的所有prepare請求的編號,那麼它就會將它已經接受過的編號最大的提案(如果有的話)作為響應反饋給proposer,同時該acceptor承諾不再接受任何編號小於n的提案。

階段二:

(a)如果proposer收到半數以上acceptor對其發出的編號為n的prepare請求的響應,那麼它就會傳送乙個針對[n,v]提案的accept請求給半數以上的acceptor。注意:v就是收到的響應中編號最大的提案的value,如果響應中不包含任何提案,那麼v就由proposer自己決定。

(b)如果acceptor收到乙個針對編號為n的提案的accept請求,只要該acceptor沒有對編號大於n的prepare請求做出過響應,它就接受該提案

一致性演算法需要保證:

如何滿足這個任務呢?下面進行推導,推導過程就回答了

為什麼演算法需要多個acceptor接受提案?

最簡單的做法就是只設定乙個acceptor多個proposer,那麼acceptor可以chosen任意proposer提出的乙個提案,chosen之後,其餘proposer傳送提案給acceptor,直接返回chosen的提案即可完成任務,但存在的問題是acceptor是單點,acceptor掛了,系統就無法工作了,所以需要設定多個acceptor避免單點問題

需求1:即使只有乙個提案被提出,演算法仍然能選出乙個提案

要滿足這個需求,演算法只需要保證p1,即可滿足需求1:

p1:乙個acceptor必須接受它收到的第乙個提案

為什麼value被選定需要被半數以上的acceptor接受?

只保證p1的話,即乙個value的選定只需要乙個acceptor接受的話,那麼如果每個proposer分別提出不同的value,發給不同的acceptor。根據p1,acceptor分別接受自己收到的value,就導致不同的value被選定。

出現了不一致。如果演算法認為value選定需要全部acceptor接受,那其實此時退化成了二階段提交協議了。

因此,我們需要讓演算法滿足:乙個value被選定需要被半數以上的acceptor接受。 因為乙個集合不可能同時存在兩個半數以上的子集同時接受兩個不同value(兩個半數以上子集必然有非空的交集,由於演算法限定只接受最大的prepare編號,導致value值在同一時刻是唯一的)。因此演算法如果能保證value被半數acceptor接受,則意味這此時被認定的value是唯一的。

為什麼acceptor要接受多個提案?

如果acceptor只能夠接受乙個提案,則可能發生所有proposer提出的提案都無法達到多數,從而無法進入選定階段。比如p1/p2/p3 向c1、c2、c3傳送提案,可能會發生c1接受p1,c2接受p2,c3接受p3,而p1、p2、p3傳送給其餘c的訊息被丟棄,導致沒有value被選定。因此acceptor必須要接受多個提案。

為什麼提案要設計成【提案=編號+value】而不是【提案=value】?

因為acceptor需要接受多個提案,如果提案就是value,考慮acceptor該如何處理新到達的提案,如果根據到達acceptor的先後順序做處理:如果先到的被接受,後面的都丟棄,那此時acceptor只能接受乙個提案;如果後到的都被接受,那麼當某value被選定之後,其他proposer提出新value只要到達接受該value的acceptor,該選定的value就會被覆蓋,從而可能導致由選定進入不選定狀態,甚至進入下個value的選定狀態,違反了一致性。如果根據value的大小做處理同樣存在選定狀態會反覆變化的可能,但由於acceptor要能接受多個提案,提案可能存在被覆蓋的情況,因此要保證可能被選定的value在被其他提案覆蓋的情況下,仍有可能保留下來,因此有了提案=全域性唯一編號+value的設計,通過編號的偏序關係定義acceptor處理提案的方式。

到這一步,當乙個提案被選定的時候,其實指的是相同的value佔到了acceptor的大多數,而其中的提案編號可能是不相同的,繼續推導,當乙個value=v被選定之後,其後被選定的提案如果value也是v,那麼所有acceptor最終都會達到一致,如果之後被選定的提案value不是v,則可能導致選定的值反覆變化,出現不一致,因此有了p2約束:

p2:如果某個value為v的提案被選定了,那麼每個編號更高的被選定提案的value必須也是v。

從p1到p2其實很難理解是如何推導出到p2的,畢竟p2之前我們只是在推導acceptor該如何處理提案、提案的設計、選定的時機等,p2卻直接約束了提案選出來之後演算法該如何執行,而p2之前的那些設計並不能保證一定能達到有乙個value被選定這個狀態。先把這個疑問留在這裡,繼續往下推導,從p2到p2b約束的推導是很直接易懂的,網上資料很多,不贅述了,比較費解的是從p2b如何推導到p2c,其實我們不需要理解當初lamport如何由p2b推導出p2c的,只需要明白滿足p2c是保證p2b的充分條件即可,這樣演算法只需要滿足p2c,即可滿足p2b>=p2a>=p2>=p1,通過保持p2c就能滿足p2b是用數學歸納法證明的:

p2b:如果某個value為v的提案被選定了,那麼之後任何proposer提出的編號更高的提案的value必須也是v。

p2c:對於任意的n和v,如果提案[n, v]被提出,那麼存在乙個半數以上的acceptor組成的集合s,滿足以下兩個條件中的任意乙個:

證明:

通過保持p2c就可保證p2b,即是證明當某個提案[n0,v0]被選定後,如果我們保持p2c即可保證之後任何proposer提出的提案nn的value是v0。(注意通過p2c如何並不能保證一定會有value被選定,只是假定在在p2c的條件下,若某value被選定後,下乙個提議的值一定是該value)。

當nn=n0+1,(反證法)假設[n0,v0]已經被選定,所屬的半數以上子集設為a,有新提案nn的值不為v0,而是v1。那麼根據p2c要麼存在一組半數以上acceptor集合b批准的提案編號都大於nn(由於a的存在,已經由一半為n0,所以這種情況不可能發生),要麼b中編號小於nn的最大的value為v1(由於a的存在,b中小於nn的編號就是n0,自然不可能為v1,所以也不可能發生),兩種情況都不會發生。

假設當nn在n0+1~nn-1之間所有提案的值都是v0,需要證明保持 p2c即可保證當nn=nn時proposer提議的值也是v0。根據p2c,需要存在乙個半數以上的子集a,要麼a中接受的提案編號都大於nn(如果滿足這條,那麼v的值可以自己選定,就可以設為v1了),但由於v0已經被選定,因此找不到乙個題案都比nn大的半數以上的子集;要麼a中接受過的小於nn的最大編號提案,因為此時已經v0已經被選定,若a中最大編號是n0,那麼nn提議的值就是v0;若a中最大編號在n0+1~nn-1之間,則根據前提假設,nn提議的值仍是v0。故得證。

推導到這裡,我們只要保證p2c即可保證若有提案被選定,則之後任意乙個proposer提議的值都可以和已選定的值保持一致

p2c只保證了若有提案被選定,可以保持選定值的一致性,但演算法如何保證一定有值會被選定呢?

之前遺留的這個問題似乎還沒解決,其實p2c也順便解決了能選出多數派的問題,因為proposer提交的value是受acceptor限制的(上輪編號的提案雖然沒有通過,但以後的提案應該繼續之前的,「與其**未來,不如限制未來」),就不會在一次選舉中提交兩個不同的value,即使能提交也會因為proposal編號問題有乙個會被拒絕,從而能保證正常情況下能形成多數派。特殊情況就是一種極端情況導致paxos演算法失去活性,始終沒有提案被選定。比如當p1提出m1提案,完成階段一,但此時p2提出m2同樣完成階段一,當p1進入第二階段時發現它選發出的accept請求全部被忽略,如此反覆,導致提案的選舉過程陷入死迴圈,為了避免這種情況發生,可以選擇乙個主proposer,規定只有主proposer才能提出提案,從而保證paxos演算法的活性。

paxos協議本身是比較簡單的,如何將paxos協議工程化,才是真正的難題。

Paxos演算法原理與推導

一 問題產生的背景 在分布式系統中,必然會存在服務宕機 或網路異常 如網路延遲 訊息亂序 訊息丟失等 等狀況。paxos基於容錯的分布式環境,實現在集群內部對某個值達成最終一致的分布式演算法。注1 服務不存在拜占庭將軍問題 不存在叛徒 也即集群內的機器可以隨時發生宕機重啟,但不能做出有違約定的行為。...

paxos演算法之粗淺理解

paxos出身 paxos出身名門,它爹是沒多久前獲得圖靈獎的在分布式領域大名鼎鼎的leslie lamport。paxos為何而生 那麼lamport 他老人家為什麼要搞這個東東呢 不是吃飽了撐的,而是為了解決分布式系統的大難題。分布式系統一 般要求具有高可用性,高可用性一般又是通過冗餘也就是多副...

深入淺出理解Paxos演算法

paxos演算法是萊斯利 蘭伯特 英語 leslie lamport latex中的 la 於1990年提出的一種基於訊息傳遞且具有高度容錯特性的一致性演算法。paxos演算法一開始非常難以理解,但是一旦理解其實也並不難,之所以難理解其實是因為作者講的故事難理解。paxos演算法維基百科 本人是在看...