PBFT算法

PBFT算法

算法前置

State Machine Replication
State Machine Replication是一項很有效的fault tolerance技術。在這個模型中,程序(比如一個apache server)被視爲 deterministic state machine ,意思就是給程序一定順序的 input requests ,程序執行後就會到達一定的狀態(準確的說是數據結果),而replication就是在多個 nodes 中保持相同的state。
給予每個replicas的input request sequence一致,在deterministic execution的前提下,這些replicas就會 reach the same exact state

摘自原文State Machine Replication 技術 和 PAXOS 算法

FLP Impossibility:
No completely asynchronous consensus protocol can tolerate even a single unannounced process death. [ Impossibility of Distributed Consensus with One Faulty Process,Journal of the Association for Computing Machinery, Vol. 32, No. 2, April 1985]
在異步網絡環境中只要有一個故障節點, 任何Consensus算法都無法保證正確結束.
摘自拜占庭將軍問題和FLP的啓示

Quorum-based voting for replica control
The quorum-based voting for replica control is due to [Gifford, 1979].[3] Each copy of a replicated data item is assigned a vote. Each operation then has to obtain a read quorum (Vr) or a write quorum (Vw) to read or write a data item, respectively. If a given data item has a total of V votes, the quorums have to obey the following rules:
1. Vr + Vw > V
2. Vw > V/2
The first rule ensures that a data item is not read and written by two transactions concurrently. Additionally, it ensures that a read quorum contains at least one site with the newest version of the data item. The second rule ensures that two write operations from two transactions cannot occur concurrently on the same data item. The two rules ensure that one-copy serializability is maintained.
這個是摘自wiki,主要思想就是一個少數服從多數。
它假設每個節點都有一個投票,第一個條件保障了讀寫不會並行執行。因爲當你拿到n>=Vw個投票時,獲得n個節點的同意,因而可以執行,而此時另一個人想要讀,它無法得到>=Vr個投票,因爲V-Vw小於Vr, 因此讀操作不會被執行。

以上概念對PBFT算法理解很有幫助!

算法介紹

以下內容參考了微軟的論文。裏面內容如有不正確或者不合理,請批評指正。

算法的概括

假設,我們有R=3f+1個節點,f個faulty節點。
View number的選取,對於每個replica都有一個編號n,假設我們一共有5個replica,編號分別爲0,1,2,3,4,初始化V=0,那麼我們的初始化view就是replica p = v mod |R|,編號爲0的replica。

  1. Client發送一個request 到各個replica,其中o代表操作,t代表請求發生的時間戳,c估計是client的信息。
  2. Replica接收到信息後,並驗證信息的真實性(簽名,MAC,PK),把信息放到log日誌裏(這些信息對以後的view change有用)。有序的執行完operation後將reply直接發送給客戶端。 ,v代表當前的view number,t代表client發送請求時產生的時間戳,i代表當前的replica,r爲結果。
  3. 當client 接收到f+1個一致性結果時,client就get到一個weak certificate。(當然接收過程都會包括一個認證過程,一下就省略)
  4. Client有一個timeout機制,如果在一定時間內沒有收到足夠的請求時,它會重新發送request到replica裏,replica如果已經執行過這個請求,它會重新發送一個reply到client(replica的每一次操作發送請求幾乎都是有記錄裏)。如果replica接收到請求的seq是不合法的,就會觸發一個view change的操作,此時認爲primary出問題了。

Normal Case Operation

現在我們只考慮單個操作,單個操作分三個階段,pre-prepare prepare commit階段。其中前兩個階段主要是爲了保證的請求執行順序(SMR理論)

fig1

上面圖,表示的是在沒有faulty節點時的pbft過程。首先client發送請求到各個replica。View節點也就是primary,爲接收的請求分配一個序列號,並廣播pre-prepare messages出去。
如果replica i之前沒有接收過具有相同n和view但degiest不同的消息,並且這個系列號是在某個區間h~H,它的view和當前記錄的view相同,身份驗證成功,replica也就是備份節點會同意這個分配,它會將 信息廣播出去,表示自己同意分配。同時會將pre-prepare與prepare信息記錄在log裏。如果replica i發送了關於request 的pre-prepare或prepare信息,那麼就稱這個request在replica中處於pre-prepared狀態。

每個replica開始收集prepare 信息,當有至少2f+1(包括自己)相匹配的時候,一個request就達到prepared狀態。(當然有可能部分節點達不到prepared狀態,如果2f+1達不到prepared狀態,理論上各個節點do nothing).

當change views時,各個replica就有可能收集的是不同view的prepare messages,進而可能2f+1節點達不到prepared狀態,此時各個節點不應執行,此時就增加了commit階段來解決這個問題。用廣播commit信息,告訴大家我的request n在view v裏已經處於prepared狀態。這樣每個節點開始收集commit,當有2f+1 commit 匹配時,就獲得了一個quorum certificate ,達到committed狀態。
此時replica就會按照seq由低到高的順序來執行請求,保證結果的正確性。同時會丟棄時間戳小於記錄裏最新消息的時間戳的請求。

View change

View change主要發生在view節點出現問題時。這個主要的idea,就在於同步信息。下面過程在不限制內存空間下進行。
這裏寫圖片描述

存儲在各個節點的數據結構:
P和Q集合,其中P集合存儲prepared狀態 n, d, v ,Q集合存儲了那些已經發送prepare或pre-prepare消息的request的信息n, d, v,meaning that i pre-prepared a request with digested with number n in view v and that request did not pre-prepare at i in a later view with the same number.
當一個節點認爲主節點壞掉了,它會進入v+1並廣播view-change消息 ,h爲replica i最新的stable check point,C包含i中的stable check point的seq和摘要。在發送之前log裏的信息都會被更新,發送之後該節點的pre-prepare,prepare,commit信息都會被刪除。
各個節點收集view number <= v 的view-change消息,得到一個quroum certificate。這樣可以排除faulty節點所發的消息。然後將view-change-ack消息發送到v+1,[view-change-ack,v+1,i,j,d] ,i爲sender,d爲view-change的摘要,j爲view-change的發出者。
新的主節點會不斷收集view-change和view-change-ack消息,這些消息可以構成一個a quorum certificate。並且把view-change消息存儲在集合S中。它在收到2f-1個關於節點i的view-change-ack消息後,證明i的view-change合理,再將其存儲到S裏。S裏的每一項都是來自不同replica的view-change消息。
大家對viewchange達成一致後,並且驗證成功,primary節點就會廣播newmessage,這個message是新的主節點會根據S裏的信息選擇的一個checkpoint和一組request。通俗的就是說要同步上一個primary執行工作中還未執行完的請求和各個節點的狀態。

Garbage Collection

這裏面有個很重要的概念就是checkpoint,這個checkpoint是用做垃圾處理的一個點。在stablecheckpoint之前的請求都是已經處理好的,因此PBFT算法會在一個間隔來清理掉stablecheckpoint以前存儲在log裏的信息,來避免無限的去佔用內存。

上面垃圾回收部分,也可以參考這篇http://blog.csdn.net/BlueCloudMatrix/article/details/51898105

實際上的實現要比論文說的還要複雜,hyperleger的PBFT算法是一個很好的實現,不愧IBM大牛,不過跟論文說的也不是完全相同!裏邊並沒有view-change-ack階段~

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章