點一下關注吧!!!非常感謝!!持續更新!!!
🚀 AI篇持續更新中!(長期更新)
目前2025年06月16日更新到:
AI煉丹日志-29 - 字節跳動 DeerFlow 深度研究框斜體樣式架 私有部署 測試上手 架構研究,持續打造實用AI工具指南!📐🤖
💻 Java篇正式開啟!(300篇)
目前2025年06月28日更新到:
Java-58 深入淺出 分布式服務 ACID 三階段提交3PC 對比2PC
MyBatis 已完結,Spring 已完結,Nginx已完結,Tomcat已完結,分布式服務正在更新!深入淺出助你打牢基礎!
📊 大數據板塊已完成多項干貨更新(300篇):
包括 Hadoop、Hive、Kafka、Flink、ClickHouse、Elasticsearch 等二十余項核心組件,覆蓋離線+實時數倉全棧!
目前2025年06月13日更新到:
大數據-278 Spark MLib - 基礎介紹 機器學習算法 梯度提升樹 GBDT案例 詳解
Paxos 算法詳解
基本介紹
Paxos 算法是由計算機科學家 Leslie Lamport 提出的一種基于消息傳遞的分布式一致性算法,這項開創性工作使他獲得了2013年圖靈獎。該算法解決了分布式系統中如何就某個值(決議)達成一致的問題,即使在部分節點失效或網絡不穩定的情況下也能保證系統一致性。
發展歷史
Paxos 算法最早由 Lamport 于 1998 年在《The Part-Time Parliament》論文中首次公開。論文采用了一種獨特的敘述方式,使用希臘的一個名為 Paxos 的小島作為比喻,詳細描述了 Paxos 小島中通過議會決議的流程,并以此命名這個算法。這種隱喻式的描述雖然富有創意,但增加了理解的難度。
在2001年,Lamport 意識到學術同行們難以理解他這種幽默的表達方式,于是重新發表了更加簡潔直接的算法描述版本《Paxos Made Simple》。這篇論文摒棄了之前的隱喻,直接闡述算法核心原理,大大提高了可理解性。
行業影響與應用
自 Paxos 問世以來,它就在分布式一致性算法領域占據主導地位,"Paxos"這個名詞幾乎成為了分布式一致性的代名詞。該算法在工業界得到了廣泛應用:
-
Google 系統應用:
- Chubby:分布式鎖服務
- Megastore:高可用性存儲系統
- Spanner:全球分布式數據庫
-
開源系統應用:
- ZooKeeper:分布式協調服務
- MySQL 5.7 的 Group Replication:取代傳統主從復制的新機制
算法優化
上面的內容中,分別從 Proposer 和 Acceptor 對提案的生成和批準兩個方面講解了 Paxos 算法在提案選定過程中的算法細節,同時也在提案的編號全局唯一的前提下,獲得了一個提案選定宣發,接下來我們再對這個初步算法做一個小優化,盡可能忽略Prepare請求。
如果Acceptor收到一個編號為N的Prepare請求,在此之前它已經響應過編號大于N的Prepare請求。根據P1a,該Acceptor不可能接受編號為N的提案。因此,該Acceptor可以忽略編號為N的Prepare請求。
通過這個優化,每個Acceptor只需要記住它已經批準的提案的最大編號以及它已經做出了Prepare請求響應的提案的最大編號,以便出現故障或節點重啟的情況下,也能保證P2c的不變性,而對于Proposer來說,只要它可以保證不會產生具體相同編號的提案,那么就可以丟棄任意的提案以及它所有運行時狀態信息。
算法描述
綜合前面的講解,我們來對Paxos算法的提案選定過程進行總結,結合 Proposer 和 Acceptor 對提案的處理邏輯,就可以得到類似的兩階段提交的算法執行過程
階段一
● Proposer 選擇一個提案編號N,然后向半數以上的 Acceptor 發送編號為N的Prepare請求
● 如果一個 Acceptor 收到一個編號為 N的Prepare請求,且N大于Acceptor已經響應過的所有Prepare請求的編號,那么它就會將它已經接受過的編號最大的提案(如果有的話)作為響應反饋給Proposer,同時該Acceptor承諾不再接受任何編號小于N的提案。
階段二
● 如果Proposer收到半數以上Acceptor對其發出的編號為N的Prepare請求的響應,那么它就會發送一個針對【N,V】提案的 Acceptor請求給半數以上的 Acceptor。注意:V就是收到的響應中編號最大的法案的Value,如果響應中不包含任何提案,那么V就是由Proposer自己決定。
● 如果Acceptor收到一個針對編號為N的提案的 Acceptor請求,只要該Acceptor沒有對編號大于N的Prepare請求做出過響應,它就接受該提案。
當然,實際運行過程中,每一個Proposer都可能產生多個提案,但只要每個Proposer都遵循如上所述的算法運行,就一定能夠保證算法執行的正確性。
Learn 學習被選定的Value
方案一
Learner 獲取了一個已經被選定的提案的前提是,該提案已經被半數以上的Acceptor批準,因此,最簡單的做法就是一旦Acceptor批準了一個提案,就將該提案發送給所有的 Learner。
很顯然,這種做法雖然可以讓Learner盡快的獲取被選定的提案,但是卻需要讓每個Acceptor與所有的Learner逐個進行一次通信,通信的次數至少為二者個數的乘積
方案二
另一種可行的方案是,我們可以讓所有的Acceptor將他們對提案的批準情況,統一發送給一個特定的Learner(稱為主 Learner),各個Learner之間可以通過消息通信來互相感知提案的選定情況,基于這樣的前提,當主Learner被通知一個提案已經被選定時,它會負責通知其他Learner
在這種方案中,Acceptor 首先會將得到的批準的提案發送給主Learner,再由其同步給其他 Learner,因此較方案一而言,方案二雖然需要多一個步驟才能將提案通知到所有的Learner,但其通信次數卻大大減少了,通常只是Acceptor和Learner的個數總和。但同時,該方案引入一個新的不穩定因素:主Learner隨時可能出現故障。
方案三
在講解方案二的時候,我們提到,方案二最大的問題在于主Learn存在單點問題,即主Learner隨時可能出現故障,因此,對方案二進行改進,可以將主Learner的范圍擴大,即Acceptor可以將批準的提案發送給一個特定的Learner集合,該集合每個Learner都可以在一個提案被選定后通知其他的Learner。這個Learner集合中的Learner個數越多,可靠性就越好,但同時網絡通信的復雜程度也就越高。
如何保證Paxos算法的活性
活性問題的定義
在分布式系統中,活性(liveness)是指系統最終一定會達成某些期望結果的性質。對于Paxos算法而言,活性具體表現為:最終一定會有一個Value被選定(accepted)。這是Paxos算法正確性的重要保證之一。
活性失效的場景分析
假設存在一種極端情況,這種場景會導致Paxos算法無法保證活性:
-
提案競爭循環:有兩個Proposer(P1和P2)持續交替提出一系列編號遞增的提案
-
死鎖形成:
- P1提出提案n1,獲得多數派Acceptance承諾
- P2提出更高編號n2(n2>n1),導致P1的提案被廢棄
- P1隨后提出更高編號n3(n3>n2),導致P2的提案被廢棄
- 這個過程不斷重復,形成"提案編號競賽"
-
具體流程示例:
- 階段1:P1準備(prepare)提案n1,獲得多數派承諾
- 階段2:P1嘗試接受(accept)提案n1,但此時P2已發出更高編號n2的準備請求
- 階段3:P2的準備請求n2獲得多數派承諾,導致n1被廢棄
- 階段4:P2嘗試接受提案n2時,P1又發出更高編號n3的準備請求
- 這個循環會無限持續下去,沒有Value最終被選定
活性問題的解決方案
為了解決這個活性問題,Paxos算法提出了以下幾種保障機制:
-
選舉主Proposer:
- 系統指定一個唯一的"主"Proposer
- 只有主Proposer可以提出提案
- 當主Proposer失效時,選舉新的主Proposer
- 這樣可以避免多個Proposer之間的競爭
-
隨機退避機制:
- 當Proposer發現提案被拒絕時,隨機等待一段時間再重試
- 等待時間隨失敗次數指數增長(類似以太網的退避算法)
- 這增加了單個Proposer成功完成提案的概率
-
提案編號限制:
- 設置提案編號的上限
- 當編號達到上限時強制選定當前最高編號的提案
- 避免無限遞增的編號競賽
-
超時機制:
- 為每個提案階段設置合理的超時時間
- 超時后自動進入下一輪提案
- 防止單個提案無限期阻塞系統
在實際工程實現中,通常采用選舉主Proposer的方案來解決活性問題,因為這種方法最可靠且易于實現。例如在Google的Chubby鎖服務和很多分布式存儲系統中都采用了這種方案。