分布式系統理論(二) 一致性協議Paxos

2022-09-02 23:06:20 字數 3233 閱讀 9667

分布式系統理論(二):一致性協議paxos

摘要: 分布式系統理論第二章,此系列主要以理論為主。

這四種角色中,proposer和acceptor比較重要,協議主要的互動邏輯都在這兩種角色中。

paxos

第一階段 prepare

client產生乙個值v,並告知proposer,我這裡產生了乙個待accept的值。

proposer收到通知後,生成乙個全域性唯一並且遞增的提案id,帶著這個id(不需要攜帶v)向集群中的所有acceptor傳送preparerequest請求。 acceptor收到preparerequest請求後,檢查一下之前接收到的提案id(包括第一階段和第二階段),新接收的提案id用n表示,之前接收到的提案id用n表示。如果n <= n,返回拒絕,並攜帶n的值。如果n > n,把n記錄下來,以後不再接收提案id比n小的提議,這時分兩種情況:

第二階段 accept

如果proposer收到大多數acceptor的拒絕應答,回到第一階段,根據接收到的最大的n,把提案id增大,繼續傳送preparerequest。

如果proposer收到大多數acceptor可以接收提議的應答,從多個應答中選出提案id最大的值(第一階段如果acceptor已經accept過值,會返回提案id最大的值),作為提案值。如果應答中沒有值,選擇client產生的值v作為提案值。然後攜帶當前的提案id,一起向集群中所有acceptor傳送accpetrequest請求。 對這段話進行解釋:第一階段client產生的值v,不一定作為accept階段的提案值。為了更快的達成一致,如果之前已經accept了值,那麼proposer會傾向於把提案值修改為之前接受的值。各個proposer不是針鋒相對,而是合作共贏。 acceptor收到accpetrequest後,檢查請求中攜帶的提案id,如果此提案id大於或等於acceptor記錄的提案id(在第一階段和第二階段,acceptor記錄最大的提案id),接受提議並記錄提案id和提案值。否則拒絕,並返回記錄的提案id。 proposer收到大多數acceptor接受提案的應答,形成決議,達成一致。

如果proposer收到大多數acceptor拒絕的應答,回到第一階段,把提案增大(增加幅度依據acceptor返回的提案id),傳送preparerequest。

舉個例子幫助理解paxos協議,把整個paxos協議的流程想象成一次競標。有兩個老闆(client),每個老闆都有乙個屬於自己的秘書(proposer),還有3個****(acceptor)。

第二階段

在上邊描述的場景中,如果在**簽約之前,p1和p2一直不停的往上加金額,就算進入第二階段,也會因為有更高的**,導致簽約失敗被打回第一階段。就像拍賣會中,多個買家一直往上飆**,最後一件東西都沒有賣出去。這種情況稱為活鎖,沒有產生阻塞,但是一直無法達成一致。

有三種解決方案:

在被打回第一階段再次發起preparerequest請求前加入隨機等待時間。

設定乙個超時時間,到達超時時間後,不再接收preparerequest請求。

在proposer中選舉出乙個leader,通過leader統一發出preparerequest和acceptrequest。

一次paxos過程(paxos instance)只能對乙個值達成一致。multi paxos是執行多個paxos instance來對多個值達成一致。

下邊以mysql組複製為例,說明multi paxos

mysql組複製中存在多個master,可以同時接受client寫入和讀取資料,並且可以保證多個master中資料一致,每一次寫入資料都會生成一條log日誌,通過paxos協議進行一致性處理,達成一致之後完成log複製。針對一系列操作,需要執行多次paxos過程(paxos instance),需要引入乙個id來標識相應的paxos instance,這裡用logid表示。每一次寫入操作,都生成乙個logid與log日誌對應,也同時與paxos instance對應,logid全域性唯一且自增。

有了logid之後,每個paxos instance獨立執行,可以對每條log日誌達成一致。這樣問題貌似已經解決了,但是還有優化的空間。

每一次paxos instance都是乙個兩階段過程(prepare和accept),所有proposer地位平等,都可以提出議題。在有多個proposer同時提出議題時,有很大概率衝突,每次衝突都會重新執行prepare階段,網路和效能開銷較大。同時paxos協議本身存在活鎖問題,有可能導致乙個議題始終無法達成一致。為了解決這兩個問題,multi paxos中引入了leader的概念,從多個proposer中選舉出乙個leader作為提議代表,每個提議都通過leader發出。這樣的話,解決了活鎖問題(活鎖問題的第三個解決方案)。因為提議都是通過leader發出,只要leader保證提案id自增,就可以跳過prepare階段,直接進行accept階段(兩階段變為一階段)。

那麼問題來了,如何選舉leader?執行一次paxos instance,提議的v就是「選舉自己為leader」。但是還有問題,一次paxos instance只能對乙個值達成一致。舉個例子:a、b、c三颱機器,執行paxos選舉leader。第一次選舉產生結果,a是leader。之後a拓機,再次執行paxos,選舉的結果還是a是leader。執行多個paxos instance(multi paxos)可以選舉出不同的leader,但是multi paxos需要選舉出乙個leader來優化網路損耗和活鎖的問題,這裡產生乙個問題遞迴依賴。

換個思路,給每乙個達成一致的值v乙個過期時間,達到過期時間清空v,這樣用乙個paxos instance就可以選出不同的leader。每台機器上都啟動乙個倒計時t,leader在存活狀態下,不斷重置t,t在倒計時為零時清空上次選舉的結果,並發起選舉。

上邊簡單說明了一種選舉leader的演算法,通過選舉leader,可以提高paxos的效能(兩階段變為一階段),並解決活鎖問題。paxos的正確性不依賴於選舉結果,在選舉失敗或者同時選出多個leader的情況下,退化為普通paxos。

paxos協議可以歸納為幾個原則:

不接受舊值(通過遞增id確定新舊)

為了更快達成一致,proposer會把值修改為最有可能達成一致的值

只有多數派接受了值,值才達成一致

一旦乙個值達成一致,不可更改

paxos是一致性協議的基礎,其他的協議(raft、zab等)都是paxos的改進版本。paxos側重理論,實現paxos非常困難。谷歌chubby**中提到,從paxos出發,在實現過程中處理了很多實際中的細節之後,已經變成另外乙個演算法了,這時候正確性無法得到理論的保證。所以才出現了許多基於paxos的改進演算法。

分布式系統架構(二) 一致性協議

分布式系統各個節點都在各自執行自己的事務操作,無法直接獲取其他節點執行結果。為保證acid特性,就需引入乙個協調者統一排程分布式節點的執行邏輯。被排程的節點稱為參與者。一 兩階段提交協議 階段一 投票 協調者 參與者傳送事務內容,尋味是否可執行事務提交操作 協調者 參與者執行事務,並返回事務執行結果...

分布式理論 一致性

什麼是分布式一致性 分布式資料一致性,指的是資料在多份副本中儲存時,各副本中的資料是一致的。副本一致性 分布式系統當中,資料往往會有多個副本。如果是一台資料庫處理所有的資料請求,那麼通過acid四原則,基本 可以保證資料的一致性。而多個副本就需要保證資料會有多份拷貝。這就帶來了同步的問題,因為我們幾...

分布式理論(三) 一致性協議之 2PC

為了使系統盡量能夠達到 cap,於是有了 base 協議,而 base 協議是在可用性和一致性之間做的取捨和妥協。人們往往需要在系統的可用性和資料一致性之間反覆的權衡。於是呢,就產生我們標題中的一致性協議,而且還不止乙個呢。為了解決分布式問題,湧現了很多經典的演算法和協議,最著名的就是二階段提交協議...