【這篇論文我翻一下來,首先感覺還是不好懂,很多地方結論的得出不夠清楚,需要讀者自己思考其中的原因。要理解Paxos算法,個人建議先搜索下介紹算法的中文文章,大致了解下Paxos算法要做什么,然后就再讀下論文,應該會有所感悟。】
Paxos Made Simple
Leslie Lamport
01 Nov 2001
說明
【說明這部分是我自己加的,下面這幾個詞大量出現與論文的主體部分,提前了解它們的含義有助于后面對于算法原理和流程的理解。】
- 議案(proposal):由提議人提出,由審批人進行初審和復審,包括議案編號和議案內容。
- 內容(value):議案的內容。
- 編號(id):議案的編號,全局唯一。
- 提議人(proposer):提出議案,接收審批人的初審和復審意見。
- 審批人(acceptoer):接收議案,根據規則決定初審和復審結果,返回給提議人。
- 執行人(learner):一旦議案成為決議,就要通知所有執行人。
- 初審(accept):議案的第一輪審核,通過后可以進行復審。
- 復審(chossen):議案的第二輪審核,通過后將成為決議。
摘要
Paxos算法,當用簡明英語表述時,灰常簡單。【大神的第一篇論文用在虛構的希臘島嶼Paxos上的人們通過議會表決法律來解釋Paxos算法,群眾紛紛表示太難理解了。大神表示你們這群渣渣不懂我的幽默,既然如此,我就用簡明英語再表述一遍,哼!】
1 介紹
Paxos算法的目標是實現一個具有容錯能力的分布式系統。人們覺得這一算法哪一理解,也許對許多讀者來說,算法最初使用希臘語表述的。[5]事實上,這一算法是分布式算法中最簡單直觀的算法之一。【Google Chubby的作者Mike Burrows:there is only one consensus protocol, and that’s Paxos– all other approaches are just broken versions of Paxos.】這一算法的核心是論文[5]中提到的一致性算法“synod”。下一章我們將看到這一算法如何嚴格遵守我們制定的規則。最后一章會通過將一致性算法應用于構建分布式系統的確定狀態機(這是分布式理論的文章最常常引用的論文的內容[4])來對Paxos算法進行完整的解釋。
2 一致性算法
2.1 問題的提出
假設我們有一組服務器,他們都可以提出議案。一致性算法要保證被提出的多個議案中最終只有一個議案可以通過審核成為決議。如果沒有議案提出,就不會產生決議。如果一個議案成為決議,那么所有process都應當知道這個決議。那么,要保證一致性就要滿足:
- 所有被提出的議案中只有一個議案可以成為決議
- 只有一個議案成為決議,且
- 服務器永遠不知道一個議案成為了決議,除非這個議案真的成為了決議
這一過程的運行時間并不重要,但要保證最終將會有某個議案成為決議,并且,一旦議案成為決議,所有服務器都能夠知道這一決議。
我們用三類代理人代表一致性算法中的三個角色:提議人、審批人和執行人。在具體實現中,單個服務器可以扮演多種代理人,我們不需要關心他們之間的對應關系。【同一臺服務器,可以即是提議人,又是審批人或執行人。】
假設代理間通過消息通信。這里我們使用傳統的異步、非拜占庭模型【不考慮拜占庭問題,代理間通信可能丟失或重復,但不會被篡改】:
- 服務器運行效率不確定,可能停機或重啟。因為當決議產生后所有服務器都有可能停機重啟,所以服務器必須能夠做到即使停機重啟也可以記住某些信息,否則停機重啟的問題將無法解決。
- 消息傳遞時間任意,消息可以重復發送,允許丟失,但不允許修改。
2.2 選擇決議
只有一個審批人的狀況是最簡單的。提議人向審批人發送議案,審批人選擇接收到的第一個議案作為決議。這個方案無法解決單機失效問題,如果審批人停機,整個系統將被阻塞。
因此,我們來嘗試另一種選擇決議的方式:讓多個審核人共同參與決議的產生。提議人向一部分審核人發送議案,審核人可能會初審通過這一議案。當足夠多的審核人初審通過這一議案時,議案就可以進行復審了。多少人算足夠多?為了保證只有一個議案成為決議,足夠多的人必須包括審核人的多數派,即半數以上的審批人。因為任何兩個多數派集合中至少有一個成員是公共的,因此只要保證一個審批人同一時間最多只能初審通過一條議案【這里指的是審批人承認這一議案通過初審,當該議案進行復審時,也會通過復審的狀態】,就可以保證最終只有一個議案可以成為決議。 (在大量論文中都涉及了多數派的研究,最早出現于[3])
在不存在服務器停機或消息丟失的前提下,我們希望即使只發起了一個議案,這個議案仍可以成為決議。因此我們需要滿足以下條件:
P1.對于接收到的第一個議案,審核人必須初審通過。
但是這一條件會產生一個問題。不同提議人幾乎同時提出不同的議案,導致每個審批人都初審通過了一個議案,但是沒有一個議案同時被半數以上的審批人初審通過。即使只有兩個議案,審批人有2n+1個,且他們分別被n個審批人初審通過,那么最后一個審批人的停機就可能導致無法產生決議。
條件P1以及決議的產生必須經過多數派審核這一條件表明審批人應當可以先后初審通過多條議案。我們通過為每一個議案分配一個編號來追蹤不同的議案,這樣一個議案就包括議案編號和議案內容兩部分。為了防止混淆,我們要求不同議案的編號也必須不同。關于這點如何保證依賴于具體實現,我們這里只是假設他成立。【google的編號生成算法在附錄,有興趣的可以看下】當一項議案被審批人中的多數派初審通過后,這項議案的內容將進入復審階段。
我們允許多個議案進入復審階段,但是我們必須保證這些議案的內容是相同的。通過引入議案編號,我們可以保證以下條件:
P2.如果一個編號為n內容為v的議案【下文用議案(n,v)替代】進入復審階段,那么所有進入復審階段的議案編號大于n的議案,他們的議案內容也為v。**
【條件P2以及后續P2的強化條件都在保證一件事:多個提議人可以提出多個議案,議案編號各不相同,但是這些議案的內容最終都會一樣】
由于議案編號是有序的,條件P2嚴格保證了只有一個議案內容可以成為決議。
要進入復審階段并最終成為決議,議案必須被至少一個審批人初審通過。因此要滿足條件P2,我們只要滿足以下條件:
P2a.如果議案(n,v)進入復審階段,那么所有通過初審的編號大于n的議案的議案內容為v。
我們仍需要滿足條件P1以保證會有決議產生。因為通信是異步的,一個議案可能被任何尚未收到過議案的審批人初審通過,這違背了條件P2a。要保證P1和P2a同時有效,需要把P2a加強為以下條件:
P2b.如果議案(n,v)進入復審階段,那么任何提議人提出的編號大于n的議案,議案內容為v。
因為一個議案首先要由提議人提出才有可能被審批人初審通過,所以條件P2b保證了條件P2a也就保證條件P2.
在找到方法滿足P2b前,我們先研究如何使這一條件成立。假設議案(m,v)進入復審階段,如何使議案編號為n且n>m的任意議案的議案內容為v 。我們使用對n使用數學歸納法證明,這樣我們要證明議案n的內容為v,就要需要額外的假設條件:任意編號在m和n-1區間內的議案的內容為v。因為議案(m,v)已經進入復審階段,那么必然有一個多數派的審批人集合C,集合中的每個審批人都對議案m初審通過。把這一結論與額外條件結合,議案m進入復審階段表明:
每個集合C中的審批人都初審通過一個編號在m和n-1區間內的議案,并且所有編號在m和n1-1區間內的議案內容為v。
【要理解這一部分,需要了解算法的具體執行過程。對于編號m到n-1的議案,議案的內容為v,提議人是怎么樣決定議案內容的呢?提議人必然是通過向集合C中的某些成員發送初審請求并通過初步審核后,從回復信息中獲知這一信息的。這就是上半句話的解釋】
因為任意審批人多數派的集合S和集合C至少有一個成員相同,那么只要保證以下條件成立,議案n的內容就可以保證為v:
P2c.對任意內容v和編號n,議案(n,v)如果被某個提議人發出,那么必然有一個審批人的多數派集合S,他們要么
(a) S中的任何審批人都沒有收到過編號小于n的議案,或者
(b) 集合S中所有審批人初審通過的編號小于n的議案中編號最大的那個議案的議案內容為v。
我們可以證明滿足條件P2c即可滿足條件P2b。
要保證條件P2c,當一個提議人想要發出一個編號為n的議案時,他必須知道已經或將要通過多數派審批人初步審核的編號小于n的議案中編號最大的那個議案的內容。要知道已經通過初審的議案很簡單,但是預測未來的初審結果很難。為了規避預測未來這一難題,審批人必須保證不會有允許這樣的初審結果出現。也就是說,提議人要求審批人一旦初審通過編號為n的議案將不得再初審通過編號小于n的議案。因此發出議案的算法如下:
1. 一個提議人生成一個新的議案編號n并發給一半以上的任意審批人,要求他們回復:
(a) 保證不再審核通過【包括初審和復審】編號小于n的議案,且**
(b) 如果已經初審通過了議案,把編號小于n且編號最大的那個議案的編號和內容回復給我。
這一過程稱為編號為n的議案的初審請求。
2. 如果提議人收到了半數以上的初審通過回復,那么他將發起一個議案,議案的編號為n,內容為v,【請注意,此時才決定議案內容,之前初步審核只是要確認議案編號是否可用】如果審批人的回復中包括議案,v就是這些議案中編號最大的那個議案的內容,如果審批人的回復中不包括議案,那么提議人可以自己設置一個議案內容。**
提議人向多數派審批人發送已經通過初審的議案(初審的多數派和這次審核的多數派成員可以不同),我們稱第二次審核的過程為復審。
以上就是提議人的算法,審批人呢?他接受兩種審批請求:初審請求和復審請求。審批人可以拒絕任意請求而不會對系統造成損害,我們應當說清楚在什么情況下審批人可以回復一個請求。在不違背初審通過時的承諾【保證不再審核通過編號小于n的議案】的前提下,他既可以初審通過又可以復審通過一個議案。換句話說:
P1a.一個審批人可以初審或復審通過一個議案(n,v),當且僅當他從未初審通過一個編號大于n的議案。
【當審批人從未收到任何議案時,他可以初審通過收到的任何議案,這符合條件P1.所以】P1a包含了P1.
我們現在擁有完整的決議產生算法并且滿足我們設定的條件——議案編號唯一。最終算法仍需要一些優化。
假設審批人收到了一個編號為n的初審請求,但是他已經初審通過了編號大于n的議案,因此已經保證過不對編號為n的議案做出回應。因為他不會初審通過這一議案,所以他沒有必要對初審請求做出回應。因此我們讓審批人忽略這一初審請求,同時,審批人也會忽略再次收到的已經初審通過的議案的初審請求。
這一優化要求審批人必須且只需記住他收到過的編號最高的議案以及他初審通過的編號最高的議案。因為P2c條件在某些角色停機的情況下仍要保證有效,審批人即使在停機重啟后仍要記的這些信息。注意提議人可以隨時放棄當前的議案或者忘掉之前提出過的議案,但是他必須保證議案的編號唯一且遞增。
把提議人和審批人的算法結合在一起,我們得到下面兩個階段的算法:
階段1
(a) 提議人生成議案編號n,向半數以上審批人發送編號為n的初審請求。
(b) 如果審批人收到的初審請求編號n大于他之前初審通過的議案編號,將回復兩個信息:一個是保證不再對編號小于n的議案做出回應【包括初審和復審】,二是如果之前初審通過了議案,將其中編號最大的議案的編號和內容回復給提議人。**
階段2
(a) 如果提議人收到了半數以上的審批人的初審通過回復,他將會以議案(n,v)發送復審請求。對于議案內容v,如果審批人的初審回復中包含議案,那么v就是這些議案中編號最大的那個議案的內容,如果初審回復中不包含議案,提議人可以自行決定議案內容v。
(b) 如果審批人收到了編號為n的議案的復審請求,只要他沒有初審通過編號大于n的議案【從而做出過保證】,他會復審通過這一議案。**
提議人可以在遵守算法規則的前提下提出多個議案。他可以在協議的任意階段隨時放棄某個議案。(算法不會因此出現問題,即使審核請求或回復在議案被拋棄后才接收到)如果其他提議人開始發起編號更高的議案,也許放棄當前編號較低的議案是個好主意。【不管編號更高的議案能否通過多數派的初審,都意味著當前編號的議案不會得到半數以上的通過回復,發送請求和等待回復將是浪費時間】因此,如果審批人因為保證過不再回復編號較小的議案而忽略某些議案時,他應當通知提議人:你的議案編號太小了,放棄當前議案,選一個更大的編號,重新發送申請。這是一個性能方面的優化,不會影響算法的正常運行。
2.3 產生決議后如何通知執行人
要隨時知道一個決議是否產生了,執行人必須能隨時獲悉是否有一個議案被半數以上審批人復審通過。首先想到的算法是,讓審批人每次復審通過一條議案,就給所有執行人發送一條消息。這使得執行人可以實時了解當前審核情況,但是這要求每個審批人和每個執行人通信,通信規模是兩者數量的乘積。
非拜占庭問題的假設使得執行人獲得消息變得簡單。我們可以選出一個執行人代表,所有審批人都與執行人代表進行通信,而當決議產生時,執行人代表再把決議通知其他執行人。這里需要一輪額外的通信以通知所有執行人當前決議。而且這一做法更不可靠,因為執行人代表也可能停機。但是他的通信量僅僅是兩者數量之和。
更進一步,我們可以讓審批人和多個執行人代表通信,每個執行人代表都可以在決議產生后通知其他執行人。多個執行人代表可以使系統更加穩定但是通信的復雜度也會提高。
由于允許通信失敗,執行人可能無法得知進入復審階段議案的內容。執行人可以向所有審批人詢問當前初審通過的議案,但是某個審批人停機就可能導致沒有一個議案被半數以上審批人初審通過。在這一情況下,只有當新的議案進入復審階段時,執行人才能知曉議案內容。如果執行人需要知道當前是否有進入復審階段的議案的內容,他可以要求提議人根據上面的算法發起一個議案。【這個新議案的議案編號足夠大,發起初審請求后能夠得到半數以上審批人的回復,他們的回復中如果有議案,議案編號最大的那個議案內容就是目前進入復審階段的議案內容。提議人可以繼續發起復審請求,也可以放棄當前議案。最終產生的決議內容是不會發生變化的。】
2.4 保證算法的進行
很容易就可以想到一個場景,兩個提議人輪流發起編號遞增的提議并通過初步審核,雖然按照算法規則,他們的提議內容是相同的,但是由于復審請求時,審批人已經初審通過了另一個編號更高的議案,導致自己的復審請求無法通過,因此永遠無法產生決議。提議人p的議案n1通過初審,然后提議人q的議案n2通過初審,n2>n1;提議人p的復審請求將被忽略,因為審批人已經保證過不再回復編號小于n2的議案。然后提議人p將議案編號提高為n3,n3>n2,并通過初步審核,導致q的復審請求也被忽略。這樣重復下去,永遠無法產生決議。【活鎖】
要保證算法進行下去,必須選出一個提議人代表,只有他可以發出議案。如果提議人代表可以和半數以上的審核人成功通信,并且他提出的議案編號比所有已經提出過的議案的編號都大,他就可以成功讓議案變成決議。如果通過審核人的忽略回復得知已經存在某些編號更高的議案,提議人代表會放棄當前議案,增大議案編號然后重新進行步驟一的初步審核,最終,提議人代表能夠選出一個足夠大的編號用于產生決議。
如果分布式系統中足夠多的部分正常工作(至少一個提議人、半數以上審批人、工作正常的通信網絡),通過選舉選出一個提議人代表就可以保證系統正常運行。Fischer,lynch和Patterson[1]的著名研究結果表明,可靠地選舉算法要么是隨機的,要么是實時的-比如使用超時機制。【另一篇文章中關于FLP理論與Paxos算法的討論:其實仔細回憶Paxos論文會發現,Paxos中存在活鎖,理論上的活鎖會導致Paxos算法無法滿足Termination屬性,也就不算一個正確的一致性算法。Lamport在自己的論文中也提到“FLP結果表明,不存在完全滿足一致性的異步算法...",因此他建議通過Leader來代替Paxos中的Proposer,而Leader則通過隨機或其他方式來選定(Paxos中假如隨機過程會極大降低FLP發生的概率)。也就是說Paxos算法其實也不算理論上完全正確的,只是在工程實現中避免了一些理論上存在的問題。但這絲毫不影響Paxos的偉大性!】但是,不管選舉成功還是失敗,系統安全性都可以得到保障。
2.5 實現
Paxos算法[5]建立在一組通過網絡通信的服務器上。在此一致性算法中,每個服務器都可以是提議人、審批人或執行人。算法選舉出一個提議人代表防止活鎖出現、選出一個執行人代表降低通信復雜度。Paxos一致性算法中的審核請求和審核回復都以普通消息的形式發送(審核回復帶有相應的議案編號防止出現消息發送失敗、延遲或重復時導致提議人的混亂)。持久化存儲保證即使停機后仍可以保存數據,用來保存審核人必須記住的信息。審核人在發送審核回復消息前,會先在持久化存儲中存儲這些消息。
最后要描述的是實現任意兩個議案編號不相同的機制。不同的提議人從互不相交的集合中選擇編號,因此兩個提議人不會生成相同的編號。每個提議人都會存儲他們發出過的最大的議案編號,當他們再次開始步驟一的初步審核申請時,會選擇一個比之前議案編號更大的編號。
3 有限狀態機的實現
實現分布式系統的一個方案是由一組客戶端向中心服務器發送指令。中心服務器作為確定狀態自動機按一定順序執行接收的指令。狀態機根據當前狀態和接收到的指令產生輸出結果和新的狀態。例如,分布式銀行系統的客戶端可能是出納員,而狀態機的狀態可能是所有賬戶余額的集合。提現操作會向狀態機發出指令,當且僅當賬戶余額不小于提現金額時,減少賬戶余額數量【新的狀態】,并返回提現前后的余額【輸出】。
單個中心服務器無法解決單機失效問題。因此我們使用一組中心服務器,每個服務器都是一個獨立的狀態機。因為狀態機屬于確定狀態自動機,所以當輸入命令的內容和順序相同時,這些狀態的狀態變化和輸出也是相同的。因此客戶端的指令發送給任何服務器都是有效的。
要保證所有服務器執行相同的狀態機指令序列,我們執行多輪paxos一致性算法,第i輪產生的決議作為指令序列中第i條狀態機指令。每個服務器都將作為提議人、審核人和執行人參與到算法中。我們假設服務器組不發生變動,每一輪算法執行都是用同一組服務器。
通常,某個服務器會被選出作為提議人代表,在每一輪算法執行時,只有代表可以提出議案。客戶端向代表發送指令,由提議人代表決定指令應該何時執行。如果代表決定某條指令應當成為指令隊列中第135條指令,他會把這條指令作為議案內容發送給審核人,最終形成決議。一般情況下總是可以成功的。但也有失敗的可能,如果出現通信失敗、停機或者另一個服務器誤以為自己也是提議人代表,并且希望另一條指令成為第135條指令。但是Paxos算法保證至多只有一條指令可以成為第135條指令。
產生這一結果的關鍵是,在Paxos一致性算法中,決議必須要經過復審才可以產生。回想一下,當議案通過初審時,提議人自己也不確定議案內容是什么,他必須根據審批人的回復來決定要么使用之前的議案內容、要么自己決定議案內容。
現在我將描述正常情況下Paxos狀態機如何工作。稍后,再來討論可能出現的風險。考慮上一個代表停機,新的代表剛剛選出的情況。(系統啟動狀態是一個特殊狀態,此時還沒有任何議案提出)
新的提議人代表,作為執行人,應當知道已經產生的指令隊列中的大部分指令。假設他知道指令1-134號,138號和139號,即第1輪到134輪,138輪和139輪算法執行的結果。(我們稍后會看到這種指令空缺是如何產生的)然后他開始執行空缺的135-137輪算法以及139輪以后的算法的初審階段。假設只有135輪和140輪的議案初審通過的回復中包含指令信息,其他輪的初審回復不包含指令信息【這里是指135輪和140輪之前已經進行過,在初審通過的返回信息中包含了之前已經進入復審階段的議案,而進入復審階段的議案是包含議案內容的,因此不需要等待客戶端發送指令請求來決定議案內容,可以直接發起復審請求】。提議人代表之后會執行135輪和140輪的復審階段,最終產生135號指令和140號指令。
提議人代表以及所有從提議人代表處了解到所有指令的服務器都可以執行1-135號指令。但是,138號-140號指令不能執行,因為136號和137號指令還沒有產生。提議人可以用接下來收到的兩條客戶端指令請求作為136號和137號指令。但是為了立即彌補指令空缺,我們用‘no-op’指令作為136號和137號指令的議案內容,這一指令不會對狀態機狀態產生影響。一旦這兩條no-op指令被選出為決議,指令138號-140號就可以執行了。
第1號-140號指令都已經產生。提議人代表也已經完成了所有編號大于140的指令的初審階段,提議人代表可以自由決定復審階段應當使用的議案內容。他把接下來收到的第一個客戶端指令請求作為141號指令進行復審。接著把收到的下一條客戶端指令作為142號,以此類推。
提議人代表不需要等待141號指令產生就可以發起142號指令的復審請求。有可能提議人發出的所有141號指令復審請求都發送失敗,可能142號指令已經產生了,執行人還不知道141號指令的內容是什么。當執行人沒有收到關于141號指令的復審請求回復時,他會再次發送請求。如果一切正常,141號指令就會成功產生。然而,這次仍有可能失敗,導致指令隊列中出現空缺。綜上,如果一個提議人可以一次產生長度為α的指令隊列,那么當指令1到指令i產生后,他可以繼續產生指令i+1到i+α。最壞的情況是產生一個α-1大小的指令空缺。【i+1輪到i+α-1輪的算法執行都沒有成功,i+α輪執行成功】
新產生的提議人代表要執行無限多次初審請求【初審請求為了確定議案的編號,不需要知道議案的內容,也就是說在收到初審通過的回復前,提議人也不知道指令內容是什么,由于整個系統中只有一個提議人發送請求,初審請求一般是一次通過的】,在上面的場景中,提議人要執行135輪-137輪以及139輪之后算法的初審階段。通過在審核回復中添加額外的信息【當前算法執行輪數】,提議人就可以在不同算法執行輪中使用相同的議案編號。在初審階段,僅當某個議案進入復審階段時,審批人在回復給其他提議人的初審通過消息中會附帶該議案的議案編號和議案內容。因此,審批人對于每一輪算法執行過程中的消息回復都可以非常精簡。【僅包括算法執行輪數和已經進入復審的議案內容】即使執行無窮多次初審階段也不會造成任何問題。
由于提議人代表停機并選擇新的提議人是非常罕見的情況,產生狀態機指令序列的效率,也就是在指令/決議上達成一致的效率僅僅取決于算法執行的復審階段。可以證明,在允許失效的情況下【停機、消息發送失敗】,Paxos算法比其他任何算法都更加高效。因此,Paxos算法絕對是一致性算法的最佳選擇。
以上討論假設提議人代表在系統中一直在線,除了當前代表停機和選出新代表間的短暫時間。在特殊情況下,新代表的選舉也可能失敗。如果沒有提議人代表在線,就無法產生新的指令。如果多個服務器都認為自己是代表,那么他們會在算法執行的每一輪都提出議案,導致活鎖,同樣使得指令無法產生。然而算法的安全性是可以保證的,兩個服務器也許會提出不同的議案,但是他們的議案內容必然是相同的。選出單個的提議人代表只是為了避免活鎖的出現。
如果服務器組可以變動,必須有辦法確定哪些服務器參與了某一輪算法的執行。最簡單的方法是通過改變狀態機狀態來實現。當前服務器組作為狀態信息的一部分,當服務器發生變化時,可以通過狀態機指令修改狀態來記錄。在執行完第i條指令后,通過標明將要參與第i+α輪算法執行的服務器組,就可以保證執行人代表可以提前發布α條指令的初審請求。這樣就實現了一個簡單地arbitrarily sophisticated reconfiguration algorithm。
參考文獻
[1] Michael J. Fischer, Nancy Lynch, and Michael S. Paterson. Impossibility of distributed consensus with one faulty process. Journal of the ACM, 32(2):374–382, April 1985.
[2] Idit Keidar and Sergio Rajsbaum. On the cost of fault-tolerant consensus when there are no faults—a tutorial. TechnicalReport MIT-LCS-TR-821, Laboratory for Computer Science, Massachusetts Institute Technology, Cambridge, MA, 02139, May 2001. also published in SIGACT News 32(2) (June 2001).
[3] Leslie Lamport. The implementation of reliable distributed multiprocess systems. Computer Networks, 2:95–114, 1978.
[4] Leslie Lamport. Time, clocks, and the ordering of events in a distributed system. Communications of the ACM, 21(7):558–565, July 1978.
[5] Leslie Lamport. The part-time parliament. ACM Transactions on Com- puter Systems, 16(2):133–169, May 1998.
附錄
議案編號生成算法
在Google的Chubby論文中給出了這樣一種方法:
假設有n個proposer,每個編號為ir(0<=ir<n)
,proposol編號的任何值s都應該大于他已知的最大值,并且滿足:s %n = ir => s = m*n + ir
proposer已知的最大值來自兩部分:proposer自己對編號自增后的值和接收到acceptor的reject后所得到的值
以3個proposer P1、P2、P3為例,開始m=0,編號分別為0,1,2
P1提交的時候發現了P2已經提交,P2編號為1 > P1的0,因此P1重新計算編號:new P1 = 1*3+0 = 4
P3以編號2提交,發現小于P1的4,因此P3重新編號:new P3 = 1*3+2 = 5