快速讀懂Paxos:Paxos made simple 小結 (一)

前言:Paxos算法很重要,但變種也很多。近來找到Lamport大神的原版論文加以梳理。 這篇論文不光解釋了Paxos算法,更重要的是闡述了這個算法是如何被思考出來的。論文link:http://lamport.azurewebsites.net/pubs/paxos-simple.pdf 


Consensus問題在distributed system領域非常關鍵,這篇論文是Lamport大神描述的Paxos算法。

背景材料:我們將agent分爲三類:proposer, acceptor, learner.

簡單來說,proposer負責提出proposal,acceptor好像是memory進行記錄,learner是最後決定的值。

 

算法思考的思路

0. 最簡單直觀的一種想法:使用一個acceptor存放proposal,把它收到的第一個proposal作爲決定值。但是這個方法有一個致命的缺點就是:單點故障導致系統不可用。

 

1. 所以,我們想找到另一種方式:使用multiple acceptor來“存放”proposal。然後,當一個value被majority的acceptor“接受”之後,它就被“chosen”

 

2. 有了這個想法,在理想情況下(即沒有failure,沒有message loss,只有一個proposed value):我們必須要有這個要求:

P1. An acceptor must accept the first proposal that it receives

 

3. 如果沒在理想環境下呢?當有多個proposer“幾乎同時”propose value的時候呢?只有P1就會出現問題。系統可能沒有一個value被”Majority”接受(設想有三個proposer同時提議,每個value只被接受了1/3)。

小結一下,我們現在的條件:

( A value is chosen only when it is accepted by a majority of acceptors,  P1)

=> An acceptor must be allowed to acceptmore than one proposal.

即通過我們的目標和P1,我們得出,一定要讓acceptor能夠“accept”超過一個的proposal(防止多個proposal“各自圈地盤不交出來”)

 

4. 如果允許一個acceptor “accept”多個proposal,我們就需要有一個方式區別proposal。這裏,我們假設不同的proposal有不同的number(如何實現是implementation層面的,比如讓不同的proposer取互不相交的數集)。根據以上的條件和目的,我們要解決問題,我們需要保證:

A value is chosen when the proposal is accepted by the majority.

稍微“變通”一點的要求就是保證:

We can allow multiple proposals to be chosen, but we must guarantee that all chosen proposals have the same value.

 

結合proposal的編號,只讓相同value的proposal被“chosen”。我們限定出如下條件即可:

P2. If a proposal with value v is chosen, then every higher-numbered proposal that is chosen has value v.

 

5. 但是P2的條件很抽象,不好直接實現。所以當我們“強化限定”P2,只讓相同value的proposal被“accepted”, 即

P2a. If a proposal with value v is chosen, then every higher-numbered proposal that accepted by any acceptor has value v.

但因爲系統是“asynchronous”。設想一個“空白的”acceptor剛“清醒”,收到了一個high-numbered proposal with different value. 那麼無論它“accept or not”,它都會違反P1或者P2a其中的一項。所以我們想要繼續“強化限定”P2a.

 

6. 只讓相同value的proposal被“issued”

 

P2b. If a proposal with value v is chosen, then every higher-numbered proposal issued by any proposer has value v.

 

我們可以看出來:

P1b => P1a=> P1

 

7. 接下來,我們想更加“明確”地知道如何才能保證P2b.

我們先回憶幾個場景:

當一個value被chosen的時候,一定是”majority”的acceptor accept了它。所以, 對於每個被chosen的value(假設是在編號m次接受的),都存在一個對應的集合C

1) 這個C是個“majority”。

2) 每個C中的元素都accept了這個value

3) Every acceptor in C has accepted a proposal with number in m..(n-1), and every proposal with number in m..(n-1) accepted by any acceptor has value v.

 

通過思考,我們可以這麼來保證P2b:

P2c. For any v and n, if a proposal with value v and number n is issued, then there is a set S consisting of a majority of acceptors such that either(a) no acceptor in S has accepted any proposal numbered less than n, or (b)v is the value of the highest-numbered proposal among all proposals numbered less than n accepted by the acceptors in S.

 

簡單說來,什麼時候一個proposal纔可以被issue呢?

- 或者 存在一個majority setS:所有的acceptor都還沒有“接受”過value(即大部分都是acceptor)

- 或者 存在一個majority setS:集合中the highest-numbered proposal的value值等於當前proposal的value值(即,之前接受的最新值就是v)。

 

設想一下,當我們有上面P2c的限定之後,我們就可以控制什麼時候才能issue proposal。而完全按照P2c的話,就可以達到P2b。

 

綜上,有以下關係:

P2c => P2b => P2a => P2

 

 

8. 接下來,我們來查看算法的實現步驟,論文中的論述比較複雜,而且算法之後的優化說的也很詳細.

 

整體說來,算法分爲兩個部分:Prepare 和 accept:

 

 

描述下來,算法的原理就是讓通過prepare和accept兩個phase來保證P1, P2c。算法的執行過程如下:

1) Proposer:先發出”prepare(n)”請求大一個majority(其實,這裏發送給所有acceptor也可以)

2) Acceptor:收到prepare(n)請求之後:

a) 如果自己沒有收到過”Prepare”,直接promise不會接受比n小的請求,返回

b) 如果已經收到過請求而且編號小於n,那麼返回它“accept”的最大編號和這個v.

3) Proposer:如果它收到了一個“majority”的acceptors給的回覆,發送accept_request(n, v)。這個v可能是:

a) 回覆中的編號最大值的v

b) 若回覆裏沒有值,將v設爲任意想要發送的值

4) Acceptor: accept 這個proposal當:

a) 沒有Prepare過編號更大的proposal

 

上面的算法是論文中的算法,其中,有許多需要細節完善的地方,可以使用不同的做法:

1) 不同的proposal有不同的編號,怎麼指定編號?論文中說可以讓不同的proposer在互不相交的數集中找編號。比如p1使用“n+1, 2n+1, 3n+1”, p2使用“n+2, 2n+2, 3n+2”......

2) 如何choose最後的值?可以有多種方式,比如讓每個acceptor都給所有learner發自己的決定信息(這樣大大增加了系統的負擔)。又比如,找出若干“特殊的learner”負責choose值,然後通知給其餘的learner。

3) Progress?如何保證這個算法能最後達到結果呢?我們可以設想一種場景:兩個proposer交替的Prepare,那麼,沒有一個proposer能成功。在這種情況下,Consensus的liveness就無法保證。我們如何做呢?我們可以使用Leader機制。讓一個Leader來爲Client發送proposal.那麼,我們如何保證有Leader呢?這就靠Eventual leader election (Ω)來保證最終會選出一個leader。所以,算法的場景變成這樣:一開始,全局leader沒選出的時候,每個client委託“自己看到的leader”來propose(使用Paxos算法來解決這幾個proposer的問題)。之後,Ω(eventual leader election <=> FD <>S <=> FD <>W)保證liveness, 會選出最後的leader。

 

上面的算法總是不是很直觀,各個roles也混在一起。經過簡化和合並,找到一個論文外的Paxos圖:

 


 

我們可以看到上面的算法實踐中,acceptor會發送ack或者reject給proposer。其實,這有點像把proposer當做“特殊的learner”。但當我們透過表象看本質,發現,原理還是論文中所闡述的。只是在原理的基礎上,可以有不同的實現。




 

 


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章