分佈式一致性算法-paxos學習筆記

分佈式一致性算法-paxos學習筆記

版權聲明:本文爲博主原創文章,未經博主允許不得轉載。

手動碼字不易,請大家尊重勞動成果,謝謝

作者:http://blog.csdn.net/wang_wbq

Paxos算法描述

以下摘自Paxos Made Simple論文:

Phase 1.

(a) A proposer selects a proposal number n and sends a prepare request with number n to a majority of acceptors.

(b) If an acceptor receives a prepare request with number n greater than that of any prepare request to which it has already responded, then it responds to the request with a promise not to accept any more proposals numbered less than n and with the highest-numbered proposal (if any) that it has accepted.


Phase 2.

(a) If the proposer receives a response to its prepare requests (numbered n) from a majority of acceptors, then it sends an accept request to each of those acceptors for a proposal numbered n with a value v, where v is the value of the highest-numbered proposal among the responses, or is any value if the responses reported no proposals.

(b) If an acceptor receives an accept request for a proposal numbered n, it accepts the proposal unless it has already responded to a prepare request having a number greater than n.


Paxos算法的目的是爲了在消息可能重複或丟失的情況下,在分佈式系統中確定一個值的最終取值。

Paxos算法中有兩個關鍵的角色組:proposeracceptor,其中acceptor組決定了整個分佈式環境的一致性。先介紹下proposeracceptor的職責:

proposer爲提案提出者,負責產生該值的可能性取值,並提交給acceptor進行決策。
proposer本地不持久化存儲數據。

acceptor爲決策者,負責批准或者拒絕一個proposer對該值的修改請求。
acceptor會在本地存儲:
1、當前已收到的最大提案編號:PN,在未收到任何消息前,該值爲空
2、當前最後一個批准的值的數據:Value,在未批准任何提案前,該值爲空

首先來看下Paxos算法:

算法前提:所有proposer提出的提案編號不能重複。


第一階段(預提案):

(a)proposer先選擇一個提案編號N(我們假設所有proposer都從0開始),並且將該編號的預提交請求Prepare(N)發送給acceptor集合中的大多數服務(一般發送給全部acceptor集合)。

(b)如果一個acceptor接收到了一個提案編號爲N的預提案請求Prepare(N),則比較其存儲的最大提案編號PNN的關係:

1、如果PN爲空,則先令PN = N,Value = null,並且同意proposer的該預提案請求,發送當前acceptor的最大提案編號PN(等於N)和最後一個批准的數據Value(爲空):PrepareResponse(PN, null)
2、如果PN < N,則先令PN = N,Value = null,並且同意proposer的該預提案請求,發送當前acceptor的最大提案編號PN(等於N)和最後一個批准的數據Value(可能爲空):PrepareResponse(PN, Value)
3、否則,拒絕該proposer的該預提案請求,發送當前acceptor的最大提案編號PN(大於N)和最後一個批准的數據Value(可能爲空):PrepareResponse(PN, Value)


第二階段(提案):

(a)當proposer的預提案Prepare(N)被acceptor集合中的大多數同意時(PN=N),則做出以下提案:

1、如果所有接收到的PrepareResponse(PN, Value)Value全部爲空(acceptor還未批准任何提案),則自己制定一個該值的取值Vn,並向acceptor集合發送提案:Proposal(N, Vn)
2、如果接收到的PrepareResponse(PN, Value)集合中存在不爲空的Value,則選取Value不爲空的PrepareResponse(PN, ValueNotNull)集合PN最大的值(PNmax, ValueNotNull),並將其作爲提案發送給acceptor集合:Proposal(PNmax, ValueNotNull)

(b)如果一個acceptor接收到一個提案編號爲N的提案Proposal(N, Vn)則:

1、如果PN爲空或者PN < N,則先令PN = N,Value = Vn,並且通過該條提案,返回:ProposalResponse(PN, Value)
2、如果PN == N並且Value爲空(尚未批准提案號爲PN的任何提案),則先令Value = Vn,並且通過該條提案,返回:ProposalResponse(PN, Value)
3、如果PN > N則拒絕該提案,返回:ProposalResponse(PN, Value)


以上爲Paxos算法的一種解釋方式,但是僅僅通過這兩輪提交可能無法確定該值和取值:
1、只有acceptor集合中的大多數中的Value值都等於一個值時才能認定該值被確定
2、通過一次提交可能由於信息丟失導致不同的acceptor批准了不同值的提案的情況

因此爲了確定該值的取值,可能需要多輪提案,下一輪提案的觸發點的一種可能情況就是:

在proposer向acceptor提交預提案之後啓動隨機定時器,如果在超時前其預提案沒有被大多數acceptor批准,則選取返回消息中最大的PN,在定時器超時後用PN + 1作爲新的預提案號進行下一輪的二階段提交。

Paxos算法合理性

paxos算法使用了集合中大多數這個保證來確定一個值是否可以被最終確定。比如N個節點集合的大多數爲N / 2 + 1。比如有5個節點則取值爲3,6個節點則取值爲4,7個節點也取值爲4。

爲什麼要使用集合中大多數這個概念呢,因爲從集合全集中任取兩個集合中大多數集合,那麼這兩個集合必定至少存在一個公共元素。這個元素就是整個paxos算法的關鍵要素。

以下證明思路非嚴格證明,只闡明思路

我們先假設一個值Value已經被一個acceptor集合的大多數批准了,我們試圖思考下這個值是否還會被改變:

如果一個proposer要決定一個提案,必須先進行兩階段提交。首先進行預提案,只有提案編號大於acceptor中保存的提案編號的預提案才能被通過,因此proposer首先選取了一個足夠大的提案編號進行預提案,acceptor會返回其接受的提案編號和當前已批准的值,由於算法規定proposer進行第二階段提交前必須獲得acceptor集合中的大多數同意,因此這個大多數acceptor集合中必定至少有一個acceptor已經批准了上述Value值,因此該提案必須使用這個提案編號最大的ValueX進行提案。

下面只需要證明這個提案編號最大的ValueX == Value即可保證值永遠不會改變。

首先假設當前Value值被在提案號爲N時被大都數acceptor批准了,因此在第N+1個提案時,其從大都數acceptor獲取預提案反饋時必定會接收到值爲Value的提案,並且其提案編號時最大的。因此第N+1個提案的Value值也必須爲Value。以此類推,之後所有的提案都不會改變該Value值的取值。

以上思路說明了一旦一個值被大多數acceptor批准,則之後的提案不會再改變這個值(提案號還是會單調增加)。

Paxos活性

我們說明了如果遵循paxos算法,一個值被選定了,則這個值永遠不會被改變,那是否存在這個值永遠不會被選定的情況呢?

proposerA使用提案編號1進行預提案獲得了大多數acceptor的通過,之後proposerB使用提案編號2進行預提案獲得了大多數acceptor的通過,proposerA使用提案編號1進行提案則會被拒絕,之後又使用提案編號3進行預提案,proposerB使用提案編號2進行提交被拒絕,使用提案編號4進行預提案。。。。。。

以上這種情況下,paxos算法出現了活鎖,因此一般在實際應用中,會首先使用paxos算法選舉出一個leader,然後由該leader作爲proposer來進行提案的二階段提交,這樣就消除了產生上述活鎖的情況。並且因爲paxos算法只能確定一個值的最終取值,往往不適用於實際應用中。通過首先選舉leader的方式可以很好地控制實現一系列值的最終取值,也能保證所有proposer提出的提案編號不能重複這個前提條件。


參考資料:
1、Paxos Made Simple
2、《從Paxos到Zookeeper分佈式一致性原理與實踐》

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