Paxos算法淺析

前言
在文章2PC/3PC究竟是啥中介紹了2PC這種一致性協議,從文中瞭解到2PC更多的被用在了狀態一致性上(分佈式事務),在數據一致性中不多被使用;而Paxos正是在數據一致性中被普遍使用,在過去十年裏,Paxos基本成爲了分佈式領域內一致性協議的代名詞。Google的粗粒度鎖服務Chubby的設計開發者Burrows曾經說過:「全部一致性協議本質上要麼是Paxos要麼是其變體」。Paxos的提出者LeslieLamport也因其對分佈式系統的傑出理論貢獻得到了2013年圖靈獎。
在介紹Paxos以前,先介紹一下數據一致性到底被用在什麼場景中,下面以副本狀態機來表述算法

副本狀態機
在分佈式環境下,一致性協議的應用場景通常會採用副本狀態機來表達,這是對各類不一樣應用場景的一種抽象化表述。
一種典型的實現副本狀態機的機制是採用Log副本的方式,以下圖(來源網上):數據庫

集羣中多臺服務器各自保存一份Log副本及內部狀態機,Log內順序記載客戶端發來的操做指令,服務器依次執行Log內的指令並將其體現到內部狀態機上,若是保證每臺機器內的Log副本內容徹底一致,那麼對應的狀態機也能夠保證總體狀態一致。
一致性協議的做用就是保證各個Log副本數據的一致性,上圖中的一致性模塊就是用來保證一致性的。
再來看一個更具體的例子:在一個分佈式數據庫系統中,若是各節點的初始狀態一致,每一個節點都執行相同的操做序列,那麼他們最後能獲得一個一致的狀態。爲保證每一個節點執行相同的命令序列,須要在每一條指令上執行一個「一致性算法」以保證每一個節點看到的指令一致。服務器

民主選舉算法
如何保證各個Log副本數據的一致性(或者說如何來實現這個一致性模塊),可能最早想到的是隻須要提供一個惟一一致性模塊,而後用相似2PC的方式來保證數據的一致性,可是咱們也知道了2PC方式中面臨着一致性模塊的當機以及網絡的異常等問題,最終致使數據出現不一致;
而本文要介紹的Paxos一致性協議就是如何在可能發生幾起宕機或網絡異常的分佈式系統中,快速且正確地在集羣內部對某個數據的值達成一致,而且保證不論發生以上任何異常,都不會破壞整個系統的一致性,主要緣由仍是Paxos提供了集羣一致性模塊,而後以民主選舉的算法——大多數的決定會成個整個集羣的統一決定。任何一個點均可以提出要修改某個數據的提案,是否經過這個提案取決於這個集羣中是否有超過半數的結點贊成(因此Paxos算法須要集羣中的結點是單數);
固然這個保證是有一個前提的,這就是下面要介紹的拜占庭問題。網絡

拜占庭問題
其故事背景是這樣的:拜占庭位於如今土耳其的伊斯坦布爾,是東羅馬帝國的首都。因爲當時拜占庭羅馬帝國國土遼闊,爲了防護目的,所以每一個軍隊都分隔很遠,將軍與將軍之間只能靠信差傳消息。 在戰爭的時候,拜占庭軍隊內全部將軍必需達成一致的共識,決定是否有贏的機會纔去攻打敵人的陣營。可是,軍隊可能有叛徒和敵軍間諜,這些叛徒將軍們會擾亂或左右決策的過程。這時候,在已知有成員謀反的狀況下,其他忠誠的將軍在不受叛徒的影響下如何達成一致的協議,這就是拜占庭將軍問題。
從理論上來講,在分佈式計算領域,試圖在異步系統和不可靠的通道上來達到一致性是不可能的,所以在對一致性的研究過程當中,都每每假設信道是可靠的,即假設不存在拜占庭問題。
非拜占庭模型定義:
1.一致性模塊的行爲能夠以任意速度執行,容許運行失敗,在失敗後也許會重啓並再次運行;
2.一致性模塊之間經過異步方式發送信息通訊,通訊時間能夠任意長,信息可能會在傳輸過程當中丟失,也容許重複發送相同的信息,多重信息的順序能夠任意。可是有一點:信息不容許被篡改。併發

Paxos的基本概念
首先是並行進程(對應副本狀態機上每臺服務器的一致性模塊)的角色概念,Paxos協議下不一樣並行進程可能承擔的三種角色以下:
倡議者(Proposer):倡議者能夠提出提議(數值或操做命令等)以供投票表決;
接受者(Acceptor):接受者能夠對倡議者提出的提議進行投票表決,從衆多提議中選出惟一肯定的一個;
學習者(Learner):學習者無倡議投票權,可是能夠從接受者那裏獲知是哪一個提議最終被選中;
在一致性協議框架中,一個並行進程能夠同時承擔以上多種角色。
劃分角色後,就能夠更精確的定義問題:
1.決議(value)只有在被 proposers 提出後才能批准(未經批准的決議稱爲「提案(proposal)」);
2.在一次Paxos算法的執行實例中,只批准一個Value;
3.Learner只能得到被批准(chosen)的Value。框架

Paxos一致性協議
Paxos的目的是在非拜占庭條件下,當多個並行進程提出不一樣的倡議時,如何可以達成一致。若是概括Paxos協議,能夠將其描述爲如下兩階段過程:
階段一:Prepare階段
1.1【倡議者視角】倡議者選擇倡議編號n,而後向大多數(即超過半數以上)接受者發送Prepare請求,請求中附帶倡議編號n。
1.2【接受者視角】對於某個接受者來講,若是接收到帶有倡議編號n的Prepare請求,則作以下判斷:若倡議編號n比此接受者以前響應過的任何其它Prepare請求附帶的倡議編號都大,那麼此接受者會給倡議者以響應,並承諾不會響應以後接收到的其它任何倡議編號小於n的請求,另外,若是接受者曾經響應過2.2階段的Accept請求,則將全部響應的Accept請求中倡議編號最高的倡議內容發送給倡議者,倡議內容包括兩項信息:Accept請求中的倡議編號以及其倡議值。若倡議編號n不比此接受者以前響應過的任何其它Prepare請求附帶的倡議編號都大,那麼此接受者不會給倡議者以響應。異步

階段二:Accept階段
2.1【倡議者視角】若是倡議者接收到大多數接受者關於帶有倡議編號n的Prepare請求的響應,那麼倡議者向這些接受者發送Accept請求,Accept請求附帶兩個信息:倡議編號n以及倡議值v。倡議值v的選擇方式以下:若是在1.2階段接受者返回了本身曾經接受的具備最高倡議編號Accept請求倡議內容,則從這些倡議內容裏面選擇倡議編號最高的並將其倡議值做爲倡議值v;若是1.2階段沒有收到任何接受者的Accept請求倡議內容,則能夠任意賦值給倡議值v。分佈式

2.2【接受者視角】若是接受者接收到了任意倡議編號爲n的Accept請求,則接受者接受此請求,除非在此期間接受者響應過具備比n更高編號的Prepare請求。經過以上兩階段過程便可選出惟一的倡議值,對於學習者來講,其須要從接受者那裏獲知究竟是哪一個倡議值被選出。一個直觀的方法以下:每當接受者執行完2.2步驟,即接受某個Accept請求後,由其通知全部學習者其所接受的倡議,這樣,學習者很快習得是哪一個倡議被最終選出。可是這種方式會致使大量通訊,由於任意一個接受者會通知任意一個學習者,若是有m個接受者,n個學習者,則須要m*n次通訊。一個替代策略是:從衆多學習者中選擇一個做爲表明,由其從接受者那裏獲知最終被選出的倡議,而後再由其通知其它學習者,這樣能夠將通訊量降爲m+n。可是這個方案中若是這個學習者表明發生故障,其它學習者無從知曉倡議值。考慮到健壯性和通訊量兩個因素,能夠採起折中方法:選出若干學習者做爲表明,由這些表明從接受者那裏獲知最終倡議值,而後通知其它學習者。學習

經過以上流程,若是有多個併發進程提出各自的倡議值,Paxos就能夠保證從中選出且只選出一個惟一肯定的倡議值,以此來達到副本狀態機保持狀態一致的目標。.net

總結

此文只是對Paxos的應用場景以及Paxos協議自己進行了介紹,而Paxos最難理解性在因而什麼因素致使協議以此種方式呈現以及其正確性證實過程而非最終協議自己內容。

我的博客:codingo.xyz

相關文章
相關標籤/搜索