版權聲明:本文爲博主原創文章,未經博主容許不得轉載。算法
手動碼字不易,請你們尊重勞動成果,謝謝promise
如下摘自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..net
(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.code
Phase 2. blog
(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.get
(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.requests
Paxos算法的目的是爲了在消息可能重複或丟失的狀況下,在分佈式系統中肯定一個值的最終取值。
Paxos算法中有兩個關鍵的角色組:proposer
和acceptor
,其中acceptor
組決定了整個分佈式環境的一致性。先介紹下proposer
和acceptor
的職責:
proposer爲提案提出者,負責產生該值的可能性取值,並提交給acceptor進行決策。
proposer本地不持久化存儲數據。
acceptor爲決策者,負責批准或者拒絕一個proposer對該值的修改請求。
acceptor會在本地存儲:
一、當前已收到的最大提案編號:PN,在未收到任何消息前,該值爲空
二、當前最後一個批准的值的數據:Value,在未批准任何提案前,該值爲空
首先來看下Paxos算法:
算法前提:全部proposer提出的提案編號不能重複。
第一階段(預提案):
(a)proposer先選擇一個提案編號N(咱們假設全部proposer都從0開始),而且將該編號的預提交請求Prepare(N)
發送給acceptor集合中的大多數服務(通常發送給所有acceptor集合)。
(b)若是一個acceptor接收到了一個提案編號爲N的預提案請求Prepare(N)
,則比較其存儲的最大提案編號PN
與N
的關係:
一、若是
PN
爲空,則先令PN = N,Value = null
,而且贊成proposer的該預提案請求,發送當前acceptor的最大提案編號PN(等於N)和最後一個批准的數據Value(爲空):PrepareResponse(PN, null)
二、若是PN < N
,則先令PN = N,Value = null
,而且贊成proposer的該預提案請求,發送當前acceptor的最大提案編號PN(等於N)和最後一個批准的數據Value(可能爲空):PrepareResponse(PN, Value)
三、不然,拒絕該proposer的該預提案請求,發送當前acceptor的最大提案編號PN(大於N)和最後一個批准的數據Value(可能爲空):PrepareResponse(PN, Value)
第二階段(提案):
(a)當proposer的預提案Prepare(N)
被acceptor集合中的大多數贊成時(PN=N),則作出如下提案:
一、若是全部接收到的
PrepareResponse(PN, Value)
中Value
所有爲空(acceptor還未批准任何提案),則本身制定一個該值的取值Vn,並向acceptor集合發送提案:Proposal(N, Vn)
二、若是接收到的PrepareResponse(PN, Value)
集合中存在不爲空的Value
,則選取Value
不爲空的PrepareResponse(PN, ValueNotNull)
集合中PN
最大的值(PNmax, ValueNotNull)
,並將其做爲提案發送給acceptor集合:Proposal(PNmax, ValueNotNull)
(b)若是一個acceptor接收到一個提案編號爲N的提案Proposal(N, Vn)
則:
一、若是
PN
爲空或者PN < N
,則先令PN = N,Value = Vn
,而且經過該條提案,返回:ProposalResponse(PN, Value)
二、若是PN == N
而且Value
爲空(還沒有批准提案號爲PN的任何提案),則先令Value = Vn
,而且經過該條提案,返回:ProposalResponse(PN, Value)
三、若是PN > N
則拒絕該提案,返回:ProposalResponse(PN, Value)
以上爲Paxos算法的一種解釋方式,可是僅僅經過這兩輪提交可能沒法肯定該值和取值:
一、只有acceptor集合中的大多數中的Value值都等於一個值時才能認定該值被肯定
二、經過一次提交可能因爲信息丟失致使不一樣的acceptor批准了不一樣值的提案的狀況
所以爲了肯定該值的取值,可能須要多輪提案,下一輪提案的觸發點的一種可能狀況就是:
在proposer向acceptor提交預提案以後啓動隨機定時器,若是在超時前其預提案沒有被大多數acceptor批准,則選取返回消息中最大的PN,在定時器超時後用
PN + 1
做爲新的預提案號進行下一輪的二階段提交。
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算法,一個值被選定了,則這個值永遠不會被改變,那是否存在這個值永遠不會被選定的狀況呢?
proposerA使用提案編號1進行預提案得到了大多數acceptor的經過,以後proposerB使用提案編號2進行預提案得到了大多數acceptor的經過,proposerA使用提案編號1進行提案則會被拒絕,以後又使用提案編號3進行預提案,proposerB使用提案編號2進行提交被拒絕,使用提案編號4進行預提案。。。。。。
以上這種狀況下,paxos算法出現了活鎖,所以通常在實際應用中,會首先使用paxos算法選舉出一個leader,而後由該leader做爲proposer來進行提案的二階段提交,這樣就消除了產生上述活鎖的狀況。而且由於paxos算法只能肯定一個值的最終取值,每每不適用於實際應用中。經過首先選舉leader的方式能夠很好地控制實現一系列值的最終取值,也能保證全部proposer提出的提案編號不能重複這個前提條件。
參考資料: 一、Paxos Made Simple 二、《從Paxos到Zookeeper分佈式一致性原理與實踐》