区块链核心技术:拜占庭共识算法之PBFT全面理解
PBFT是Practical Byzantine Fault Tolerance的縮寫,意為實(shí)用拜占庭容錯(cuò)算法。該算法是Miguel Castro (卡斯特羅)和Barbara Liskov(利斯科夫)在1999年提出來的,解決了原始拜占庭容錯(cuò)算法效率不高的問題,將算法復(fù)雜度由指數(shù)級(jí)降低到多項(xiàng)式級(jí),使得拜占庭容錯(cuò)算法在實(shí)際系統(tǒng)應(yīng)用中變得可行。該論文發(fā)表在1999年的操作系統(tǒng)設(shè)計(jì)與實(shí)現(xiàn)國際會(huì)議上(OSDI99)。沒錯(cuò),這個(gè)Loskov就是提出著名的里氏替換原則(LSP)的人,2008年圖靈獎(jiǎng)得主。
摘要部分
OSDI99這篇論文描述了一種副本復(fù)制(replication)算法解決拜占庭容錯(cuò)問題。作者認(rèn)為拜占庭容錯(cuò)算法將會(huì)變得更加重要,因?yàn)閻阂夤艉蛙浖e(cuò)誤的發(fā)生將會(huì)越來越多,并且導(dǎo)致失效的節(jié)點(diǎn)產(chǎn)生任意行為。(拜占庭節(jié)點(diǎn)的任意行為有可能誤導(dǎo)其他副本節(jié)點(diǎn)產(chǎn)生更大的危害,而不僅僅是宕機(jī)失去響應(yīng)。)而早期的拜占庭容錯(cuò)算法或者基于同步系統(tǒng)的假設(shè),或者由于性能太低而不能在實(shí)際系統(tǒng)中運(yùn)作。這篇論文中描述的算法是實(shí)用的,因?yàn)樵撍惴梢怨ぷ髟诋惒江h(huán)境中,并且通過優(yōu)化在早期算法的基礎(chǔ)上把響應(yīng)性能提升了一個(gè)數(shù)量級(jí)以上。作者使用這個(gè)算法實(shí)現(xiàn)了拜占庭容錯(cuò)的網(wǎng)絡(luò)文件系統(tǒng)(NFS),性能測(cè)試證明了該系統(tǒng)僅比無副本復(fù)制的標(biāo)準(zhǔn)NFS慢了3%。
1.概要介紹
第一段大片廢話就是說明拜占庭算法越來越重要了,然后說這篇論文提出解決拜占庭容錯(cuò)的狀態(tài)機(jī)副本復(fù)制(state machine replication)算法。這個(gè)算法在保證活性和安全性(liveness & safety)的前提下提供了(n-1)/3的容錯(cuò)性。從Lamport教授在1982年提出拜占庭問題開始,已經(jīng)有一大堆算法去解決拜占庭容錯(cuò)了。但是一句話概括:這些算法都是狗屎!PBFT算法跟這些妖艷賤貨完全不同,在只讀操作中只使用1次消息往返(message round trip),在只寫操作中只使用2次消息往返,并且在正常操作中使用了消息驗(yàn)證編碼(Message Authentication Code,簡(jiǎn)稱MAC),而造成妖艷賤貨性能低下的公鑰加密(public-key cryptography)只在發(fā)生失效的情況下使用。作者不僅提出算法,而且使用這個(gè)算法實(shí)現(xiàn)了一個(gè)牛逼的系統(tǒng)(拜占庭容錯(cuò)的NFS),反正性能杠杠的。
作者先炫耀一下這邊論文的貢獻(xiàn)亮瞎你們的狗眼:
1)首次提出在異步網(wǎng)絡(luò)環(huán)境下使用狀態(tài)機(jī)副本復(fù)制協(xié)議
2)使用多種優(yōu)化使性能顯著提升
3)實(shí)現(xiàn)了一種拜占庭容錯(cuò)的分布式文件系統(tǒng)
4)為副本復(fù)制的性能損耗提供試驗(yàn)數(shù)據(jù)支持
2.系統(tǒng)模型
這部分主要對(duì)節(jié)點(diǎn)行為和網(wǎng)絡(luò)環(huán)境進(jìn)行劇情設(shè)定,然后賦予了消息的加密屬性,最后對(duì)大魔王的能力進(jìn)行設(shè)定。
系統(tǒng)假設(shè)為異步分布式的,通過網(wǎng)絡(luò)傳輸?shù)南⒖赡軄G失、延遲、重復(fù)或者亂序。作者假設(shè)節(jié)點(diǎn)的失效必須是獨(dú)立發(fā)生的,也就是說代碼、操作系統(tǒng)和管理員密碼這些東西在各個(gè)節(jié)點(diǎn)上是不一樣的。(那么如果節(jié)點(diǎn)失效不獨(dú)立發(fā)生,PBFT算法就失效了嗎?)
作者使用了加密技術(shù)來防止欺騙攻擊和重播攻擊,以及檢測(cè)被破壞的消息。消息包含了公鑰簽名(其實(shí)就是RSA算法)、消息驗(yàn)證編碼(MAC)和無碰撞哈希函數(shù)生成的消息摘要(message digest)。使用m表示消息,mi表示由節(jié)點(diǎn)i簽名的消息,D(m)表示消息m的摘要。按照慣例,只對(duì)消息的摘要簽名,并且附在消息文本的后面。并且假設(shè)所有的節(jié)點(diǎn)都知道其他節(jié)點(diǎn)的公鑰以進(jìn)行簽名驗(yàn)證。
系統(tǒng)允許大魔王可以操縱多個(gè)失效節(jié)點(diǎn)、延遲通訊、甚至延遲正確節(jié)點(diǎn)來毀滅世界。但是作者限定大魔王不能無限期地延遲正確的節(jié)點(diǎn),并且大魔王算力有限不能破解加密算法。例如,大魔王不能偽造正確節(jié)點(diǎn)的有效簽名,不能從摘要數(shù)據(jù)反向計(jì)算出消息內(nèi)容,或者找到兩個(gè)有同樣摘要的消息。
3.服務(wù)屬性
這部分描述了副本復(fù)制服務(wù)的特性
論文算法實(shí)現(xiàn)的是一個(gè)具有確定性的副本復(fù)制服務(wù),這個(gè)服務(wù)包括了一個(gè)狀態(tài)(state)和多個(gè)操作(operations)。這些操作不僅能夠進(jìn)行簡(jiǎn)單讀寫,而且能夠基于狀態(tài)和操作參數(shù)進(jìn)行任意確定性的計(jì)算??蛻舳讼蚋北緩?fù)制服務(wù)發(fā)起請(qǐng)求來執(zhí)行操作,并且阻塞以等待回復(fù)。副本復(fù)制服務(wù)由n個(gè)節(jié)點(diǎn)組成。
針對(duì)安全性
算法在失效節(jié)點(diǎn)數(shù)量不超過(n-1)/3的情況下同時(shí)保證安全性和活性(safety & liveness)。安全性是指副本復(fù)制服務(wù)滿足線性一致性(linearizability),就像中心化系統(tǒng)一樣原子化執(zhí)行操作。安全性要求失效副本的數(shù)量不超過上限,但是對(duì)客戶端失效的數(shù)量和是否與副本串謀不做限制。系統(tǒng)通過訪問控制來限制失效客戶端可能造成的破壞,審核客戶端并阻止客戶端發(fā)起無權(quán)執(zhí)行的操作。同時(shí),服務(wù)可以提供操作來改變一個(gè)客戶端的訪問權(quán)限。因?yàn)樗惴ūWC了權(quán)限撤銷操作可以被所有客戶端觀察到,這種方法可以提供強(qiáng)大的機(jī)制從失效的客戶端攻擊中恢復(fù)。
針對(duì)活性
算法不依賴同步提供安全性,因此必須依靠同步提供活性。否則,這個(gè)算法就可以被用來在異步系統(tǒng)中實(shí)現(xiàn)共識(shí),而這是不可能的(由Fischer1985的論文證明)。本文的算法保證活性,即所有客戶端最終都會(huì)收到針對(duì)他們請(qǐng)求的回復(fù),只要失效副本的數(shù)量不超過(n-1)/3,并且延遲delay(t)不會(huì)無限增長(zhǎng)。這個(gè)delay(t)表示t時(shí)刻發(fā)出的消息到它被目標(biāo)最終接收的時(shí)間間隔,假設(shè)發(fā)送者持續(xù)重傳直到消息被接收。這時(shí)一個(gè)相當(dāng)弱的同步假設(shè),因?yàn)樵谡鎸?shí)系統(tǒng)中網(wǎng)絡(luò)失效最終都會(huì)被修復(fù)。但是這就規(guī)避了Fischer1985提出的異步系統(tǒng)無法達(dá)成共識(shí)的問題。
下面這段話是關(guān)鍵
本文的算法彈性是達(dá)到最優(yōu)的:當(dāng)存在f個(gè)失效節(jié)點(diǎn)時(shí)必須保證存在至少3f+1
個(gè)副本數(shù)量,這樣才能保證在異步系統(tǒng)中提供安全性和活性。這么多數(shù)量的副本是需要的,因?yàn)樵谕琻-f個(gè)節(jié)點(diǎn)通訊后系統(tǒng)必須做出正確判斷,由于f個(gè)副本有可能失效而不發(fā)回響應(yīng)。但是,有可能f個(gè)沒有失效的副本不發(fā)回響應(yīng)(是因?yàn)榫W(wǎng)絡(luò)延遲嗎?),因此f個(gè)發(fā)回響應(yīng)的副本有可能是失效的。盡管如此,系統(tǒng)仍舊需要足夠數(shù)量非失效節(jié)點(diǎn)的響應(yīng),并且這些非失效節(jié)點(diǎn)的響應(yīng)數(shù)量必須超過失效節(jié)點(diǎn)的響應(yīng)數(shù)量,即n-2f>f,因此得到n>3f。
算法不能解決信息保密的問題,失效的副本有可能將信息泄露給攻擊者。在一般情況下不可能提供信息保密,因?yàn)榉?wù)操作需要使用參數(shù)和服務(wù)狀態(tài)處理任意的計(jì)算,所有的副本都需要這些信息來有效執(zhí)行操作。當(dāng)然,還是有可能在存在惡意副本的情況下通過秘密分享模式(secret sharing scheme)來實(shí)現(xiàn)私密性,因?yàn)閰?shù)和部分狀態(tài)對(duì)服務(wù)操作來說是不可見的。
4.算法
PBFT是一種狀態(tài)機(jī)副本復(fù)制算法,即服務(wù)作為狀態(tài)機(jī)進(jìn)行建模,狀態(tài)機(jī)在分布式系統(tǒng)的不同節(jié)點(diǎn)進(jìn)行副本復(fù)制。每個(gè)狀態(tài)機(jī)的副本都保存了服務(wù)的狀態(tài),同時(shí)也實(shí)現(xiàn)了服務(wù)的操作。將所有的副本組成的集合使用大寫字母R表示,使用0到|R|-1的整數(shù)表示每一個(gè)副本。為了描述方便,假設(shè)|R|=3f+1,這里f是有可能失效的副本的最大個(gè)數(shù)。盡管可以存在多于3f+1個(gè)副本,但是額外的副本除了降低性能之外不能提高可靠性。
PBFT的劇情緩緩展開,首先介紹舞臺(tái)(view)、演員(replica)和角色(primary、backups)
所有的副本在一個(gè)被稱為視圖(View)的輪換過程(succession of configuration)中運(yùn)作。在某個(gè)視圖中,一個(gè)副本作為主節(jié)點(diǎn)(primary),其他的副本作為備份(backups)。視圖是連續(xù)編號(hào)的整數(shù)。主節(jié)點(diǎn)由公式p = v mod |R|計(jì)算得到,這里v是視圖編號(hào),p是副本編號(hào),|R|是副本集合的個(gè)數(shù)。當(dāng)主節(jié)點(diǎn)失效的時(shí)候就需要啟動(dòng)視圖更換(view change)過程。Viewstamped Replication算法和Paxos算法就是使用類似方法解決良性容錯(cuò)的。
PBFT算法的狗血?jiǎng)∏槿缦?#xff1a;
1.客戶端向主節(jié)點(diǎn)發(fā)送請(qǐng)求調(diào)用服務(wù)操作
2.主節(jié)點(diǎn)通過廣播將請(qǐng)求發(fā)送給其他副本
3.所有副本都執(zhí)行請(qǐng)求并將結(jié)果發(fā)回客戶端
4.客戶端需要等待f+1個(gè)不同副本節(jié)點(diǎn)發(fā)回相同的結(jié)果,作為整個(gè)操作的最終結(jié)果。
同所有的狀態(tài)機(jī)副本復(fù)制技術(shù)一樣,PBFT對(duì)每個(gè)副本節(jié)點(diǎn)提出了兩個(gè)限定條件:(1)所有節(jié)點(diǎn)必須是確定性的。也就是說,在給定狀態(tài)和參數(shù)相同的情況下,操作執(zhí)行的結(jié)果必須相同;(2)所有節(jié)點(diǎn)必須從相同的狀態(tài)開始執(zhí)行。在這兩個(gè)限定條件下,即使失效的副本節(jié)點(diǎn)存在,PBFT算法對(duì)所有非失效副本節(jié)點(diǎn)的請(qǐng)求執(zhí)行總順序達(dá)成一致,從而保證安全性。
接下去描述簡(jiǎn)化版本的PBFT算法,忽略磁盤空間不足和消息重傳等細(xì)節(jié)內(nèi)容。并且,本文假設(shè)消息驗(yàn)證過程是通過數(shù)字簽名方法實(shí)現(xiàn)的,而不是更加高效的基于消息驗(yàn)證編碼(MAC)的方法。
4.1客戶端
客戶端c向主節(jié)點(diǎn)發(fā)送<REQUEST,o,t,c>請(qǐng)求執(zhí)行狀態(tài)機(jī)操作o,這里時(shí)間戳t用來保證客戶端請(qǐng)求只會(huì)執(zhí)行一次??蛻舳薱發(fā)出請(qǐng)求的時(shí)間戳是全序排列的,后續(xù)發(fā)出的請(qǐng)求比早先發(fā)出的請(qǐng)求擁有更高的時(shí)間戳。例如,請(qǐng)求發(fā)起時(shí)的本地時(shí)鐘值可以作為時(shí)間戳。
每個(gè)由副本節(jié)點(diǎn)發(fā)給客戶端的消息都包含了當(dāng)前的視圖編號(hào),使得客戶端能夠跟蹤視圖編號(hào),從而進(jìn)一步推算出當(dāng)前主節(jié)點(diǎn)的編號(hào)??蛻舳送ㄟ^點(diǎn)對(duì)點(diǎn)消息向它自己認(rèn)為的主節(jié)點(diǎn)發(fā)送請(qǐng)求,然后主節(jié)點(diǎn)自動(dòng)將該請(qǐng)求向所有備份節(jié)點(diǎn)進(jìn)行廣播。
副本發(fā)給客戶端的響應(yīng)為<REPLY,v,t,c,i,r>,v是視圖編號(hào),t是時(shí)間戳,i是副本的編號(hào),r是請(qǐng)求執(zhí)行的結(jié)果。
客戶端等待f+1個(gè)從不同副本得到的同樣響應(yīng),同樣響應(yīng)需要保證簽名正確,并且具有同樣的時(shí)間戳t和執(zhí)行結(jié)果r。這樣客戶端才能把r作為正確的執(zhí)行結(jié)果,因?yàn)槭У母北竟?jié)點(diǎn)不超過f個(gè),所以f+1個(gè)副本的一致響應(yīng)必定能夠保證結(jié)果是正確有效的。
如果客戶端沒有在有限時(shí)間內(nèi)收到回復(fù),請(qǐng)求將向所有副本節(jié)點(diǎn)進(jìn)行廣播。如果請(qǐng)求已經(jīng)在副本節(jié)點(diǎn)處理過了,副本就向客戶端重發(fā)一遍執(zhí)行結(jié)果。如果請(qǐng)求沒有在副本節(jié)點(diǎn)處理過,該副本節(jié)點(diǎn)將把請(qǐng)求轉(zhuǎn)發(fā)給主節(jié)點(diǎn)。如果主節(jié)點(diǎn)沒有將該請(qǐng)求進(jìn)行廣播,那么就有認(rèn)為主節(jié)點(diǎn)失效,如果有足夠多的副本節(jié)點(diǎn)認(rèn)為主節(jié)點(diǎn)失效,則會(huì)觸發(fā)一次視圖變更。
本文假設(shè)客戶端會(huì)等待上一個(gè)請(qǐng)求完成才會(huì)發(fā)起下一個(gè)請(qǐng)求,但是只要能夠保證請(qǐng)求順序,可以允許請(qǐng)求是異步的。
4.2 PBFT算法主線流程(正常情況)
世界格局
每個(gè)副本節(jié)點(diǎn)的狀態(tài)都包含了服務(wù)的整體狀態(tài),副本節(jié)點(diǎn)上的消息日志(message log)包含了該副本節(jié)點(diǎn)接受(accepted)的消息,并且使用一個(gè)整數(shù)表示副本節(jié)點(diǎn)的當(dāng)前視圖編號(hào)。
事件的導(dǎo)火索
當(dāng)主節(jié)點(diǎn)p收到客戶端的請(qǐng)求m,主節(jié)點(diǎn)將該請(qǐng)求向所有副本節(jié)點(diǎn)進(jìn)行廣播,由此一場(chǎng)轟轟烈烈的三階段協(xié)議(three-phase protocol)拉開了序幕。在這里,至于什么消息過多需要緩存的情況我們就不管了,這不是重點(diǎn)。
三個(gè)階段的任務(wù)
我們重點(diǎn)討論預(yù)準(zhǔn)備(pre-prepare)、準(zhǔn)備(prepare)和確認(rèn)(commit)這三個(gè)歷史性階段。預(yù)準(zhǔn)備和準(zhǔn)備兩個(gè)階段用來確保同一個(gè)視圖中請(qǐng)求發(fā)送的時(shí)序性(即使對(duì)請(qǐng)求進(jìn)行排序的主節(jié)點(diǎn)失效了),準(zhǔn)備和確認(rèn)兩個(gè)階段用來確保在不同的視圖之間的確認(rèn)請(qǐng)求是嚴(yán)格排序的。
預(yù)準(zhǔn)備階段
在預(yù)準(zhǔn)備階段,主節(jié)點(diǎn)分配一個(gè)序列號(hào)n給收到的請(qǐng)求,然后向所有備份節(jié)點(diǎn)群發(fā)預(yù)準(zhǔn)備消息,預(yù)準(zhǔn)備消息的格式為<<PRE-PREPARE,v,n,d>,m>,這里v是視圖編號(hào),m是客戶端發(fā)送的請(qǐng)求消息,d是請(qǐng)求消息m的摘要。
請(qǐng)求本身是不包含在預(yù)準(zhǔn)備的消息里面的,這樣就能使預(yù)準(zhǔn)備消息足夠小,因?yàn)轭A(yù)準(zhǔn)備消息的目的是作為一種證明,確定該請(qǐng)求是在視圖v中被賦予了序號(hào)n,從而在視圖變更的過程中可以追索。另外一個(gè)層面,將“請(qǐng)求排序協(xié)議”和“請(qǐng)求傳輸協(xié)議”進(jìn)行解耦,有利于對(duì)消息傳輸?shù)男蔬M(jìn)行深度優(yōu)化。
備份節(jié)點(diǎn)對(duì)預(yù)準(zhǔn)備消息的態(tài)度
只有滿足以下條件,各個(gè)備份節(jié)點(diǎn)才會(huì)接受一個(gè)預(yù)準(zhǔn)備消息:
水線存在的意義在于防止一個(gè)失效節(jié)點(diǎn)使用一個(gè)很大的序號(hào)消耗序號(hào)空間。
進(jìn)入準(zhǔn)備階段
如果備份節(jié)點(diǎn)i接受了預(yù)準(zhǔn)備消息<<PRE-PREPARE,v,n,d>,m>,則進(jìn)入準(zhǔn)備階段。在準(zhǔn)備階段的同時(shí),該節(jié)點(diǎn)向所有副本節(jié)點(diǎn)發(fā)送準(zhǔn)備消息<PREPARE,v,n,d,i>,并且將預(yù)準(zhǔn)備消息和準(zhǔn)備消息寫入自己的消息日志。如果看預(yù)準(zhǔn)備消息不順眼,就什么都不做。
接受準(zhǔn)備消息需要滿足的條件
包括主節(jié)點(diǎn)在內(nèi)的所有副本節(jié)點(diǎn)在收到準(zhǔn)備消息之后,對(duì)消息的簽名是否正確,視圖編號(hào)是否一致,以及消息序號(hào)是否滿足水線限制這三個(gè)條件進(jìn)行驗(yàn)證,如果驗(yàn)證通過則把這個(gè)準(zhǔn)備消息寫入消息日志中。
準(zhǔn)備階段完成的標(biāo)志
我們定義準(zhǔn)備階段完成的標(biāo)志為副本節(jié)點(diǎn)i將(m,v,n,i)記入其消息日志,其中m是請(qǐng)求內(nèi)容,預(yù)準(zhǔn)備消息m在視圖v中的編號(hào)n,以及2f個(gè)從不同副本節(jié)點(diǎn)收到的與預(yù)準(zhǔn)備消息一致的準(zhǔn)備消息。每個(gè)副本節(jié)點(diǎn)驗(yàn)證預(yù)準(zhǔn)備和準(zhǔn)備消息的一致性主要檢查:視圖編號(hào)v、消息序號(hào)n和摘要d。
預(yù)準(zhǔn)備階段和準(zhǔn)備階段確保所有正常節(jié)點(diǎn)對(duì)同一個(gè)視圖中的請(qǐng)求序號(hào)達(dá)成一致。接下去是對(duì)這個(gè)結(jié)論的形式化證明:如果prepared(m,v,n,i)為真,則prepared(m',v,n,j)必不成立,這就意味著至少f+1個(gè)正常節(jié)點(diǎn)在視圖v的預(yù)準(zhǔn)備或者準(zhǔn)備階段發(fā)送了序號(hào)為n的消息m。
進(jìn)入確認(rèn)階段
當(dāng)(m,v,n,i)條件為真的時(shí)候,副本i將<COMMIT,v,n,D(m),i>向其他副本節(jié)點(diǎn)廣播,于是就進(jìn)入了確認(rèn)階段。每個(gè)副本接受確認(rèn)消息的條件是:1)簽名正確;2)消息的視圖編號(hào)與節(jié)點(diǎn)的當(dāng)前視圖編號(hào)一致;3)消息的序號(hào)n滿足水線條件,在h和H之間。一旦確認(rèn)消息的接受條件滿足了,則該副本節(jié)點(diǎn)將確認(rèn)消息寫入消息日志中。(補(bǔ)充:需要將針對(duì)某個(gè)請(qǐng)求的所有接受的消息寫入日志,這個(gè)日志可以是在內(nèi)存中的)。
接受確認(rèn)消息需要滿足的條件
我們定義確認(rèn)完成committed(m,v,n)為真得條件為:任意f+1個(gè)正常副本節(jié)點(diǎn)集合中的所有副本i其prepared(m,v,n,i)為真;本地確認(rèn)完成committed-local(m,v,n,i)為真的條件為:prepared(m,v,n,i)為真,并且i已經(jīng)接受了2f+1個(gè)確認(rèn)(包括自身在內(nèi))與預(yù)準(zhǔn)備消息一致。確認(rèn)與預(yù)準(zhǔn)備消息一致的條件是具有相同的視圖編號(hào)、消息序號(hào)和消息摘要。
確認(rèn)被接受的形式化描述
確認(rèn)階段保證了以下這個(gè)不變式(invariant):對(duì)某個(gè)正常節(jié)點(diǎn)i來說,如果committed-local(m,v,n,i)為真則committed(m,v,n)也為真。這個(gè)不變式和視圖變更協(xié)議保證了所有正常節(jié)點(diǎn)對(duì)本地確認(rèn)的請(qǐng)求的序號(hào)達(dá)成一致,即使這些請(qǐng)求在每個(gè)節(jié)點(diǎn)的確認(rèn)處于不同的視圖。更進(jìn)一步地講,這個(gè)不變式保證了任何正常節(jié)點(diǎn)的本地確認(rèn)最終會(huì)確認(rèn)f+1個(gè)更多的正常副本。
故事的終結(jié)
每個(gè)副本節(jié)點(diǎn)i在committed-local(m,v,n,i)為真之后執(zhí)行m的請(qǐng)求,并且i的狀態(tài)反映了所有編號(hào)小于n的請(qǐng)求依次順序執(zhí)行。這就確保了所有正常節(jié)點(diǎn)以同樣的順序執(zhí)行所有請(qǐng)求,這樣就保證了算法的正確性(safety)。在完成請(qǐng)求的操作之后,每個(gè)副本節(jié)點(diǎn)都向客戶端發(fā)送回復(fù)。副本節(jié)點(diǎn)會(huì)把時(shí)間戳比已回復(fù)時(shí)間戳更小的請(qǐng)求丟棄,以保證請(qǐng)求只會(huì)被執(zhí)行一次。
我們不依賴于消息的順序傳遞,因此某個(gè)副本節(jié)點(diǎn)可能亂序確認(rèn)請(qǐng)求。因?yàn)槊總€(gè)副本節(jié)點(diǎn)在請(qǐng)求執(zhí)行之前已經(jīng)將預(yù)準(zhǔn)備、準(zhǔn)備和確認(rèn)這三個(gè)消息記錄到了日志中,這樣亂序就不成問題了。(為什么?)
下圖展示了在沒有發(fā)生主節(jié)點(diǎn)失效的情況下算法的正常執(zhí)行流程,其中副本0是主節(jié)點(diǎn),副本3是失效節(jié)點(diǎn),而C是客戶端。
PBFT算法流程
4.3 垃圾回收
為了節(jié)省內(nèi)存,系統(tǒng)需要一種將日志中的無異議消息記錄刪除的機(jī)制。為了保證系統(tǒng)的安全性,副本節(jié)點(diǎn)在刪除自己的消息日志前,需要確保至少f+1個(gè)正常副本節(jié)點(diǎn)執(zhí)行了消息對(duì)應(yīng)的請(qǐng)求,并且可以在視圖變更時(shí)向其他副本節(jié)點(diǎn)證明。另外,如果一些副本節(jié)點(diǎn)錯(cuò)過部分消息,但是這些消息已經(jīng)被所有正常副本節(jié)點(diǎn)刪除了,這就需要通過傳輸部分或者全部服務(wù)狀態(tài)實(shí)現(xiàn)該副本節(jié)點(diǎn)的同步。因此,副本節(jié)點(diǎn)同樣需要證明狀態(tài)的正確性。
在每一個(gè)操作執(zhí)行后都生成這樣的證明是非常消耗資源的。因此,證明過程只有在請(qǐng)求序號(hào)可以被某個(gè)常數(shù)(比如100)整除的時(shí)候才會(huì)周期性地進(jìn)行。我們將這些請(qǐng)求執(zhí)行后得到的狀態(tài)稱作檢查點(diǎn)(checkpoint),并且將具有證明的檢查點(diǎn)稱作穩(wěn)定檢查點(diǎn)(stable checkpoint)。
副本節(jié)點(diǎn)保存了服務(wù)狀態(tài)的多個(gè)邏輯拷貝,包括最新的穩(wěn)定檢查點(diǎn),零個(gè)或者多個(gè)非穩(wěn)定的檢查點(diǎn),以及一個(gè)當(dāng)前狀態(tài)。寫時(shí)復(fù)制技術(shù)可以被用來減少存儲(chǔ)額外狀態(tài)拷貝的空間開銷。
檢查點(diǎn)的正確性證明的生成過程如下:當(dāng)副本節(jié)點(diǎn)i生成一個(gè)檢查點(diǎn)后,向其他副本節(jié)點(diǎn)廣播檢查點(diǎn)消息<CHECKPOINT,n,d,i>,這里n是最近一個(gè)影響狀態(tài)的請(qǐng)求序號(hào),d是狀態(tài)的摘要。每個(gè)副本節(jié)點(diǎn)都默默地在各自的日志中收集并記錄其他節(jié)點(diǎn)發(fā)過來的檢查點(diǎn)消息,直到收到來自2f+1個(gè)不同副本節(jié)點(diǎn)的具有相同序號(hào)n和摘要d的檢查點(diǎn)消息。這2f+1
個(gè)消息就是這個(gè)檢查點(diǎn)的正確性證明。
具有證明的檢查點(diǎn)成為穩(wěn)定檢查點(diǎn),然后副本節(jié)點(diǎn)就可以將所有序號(hào)小于等于n的預(yù)準(zhǔn)備、準(zhǔn)備和確認(rèn)消息從日志中刪除。同時(shí)也可以將之前的檢查點(diǎn)和檢查點(diǎn)消息一并刪除。
檢查點(diǎn)協(xié)議可以用來更新水線(watermark)的高低值(h和H),這兩個(gè)高低值限定了可以被接受的消息。水線的低值h與最近穩(wěn)定檢查點(diǎn)的序列號(hào)相同,而水線的高值H=h+k,k需要足夠大才能使副本不至于為了等待穩(wěn)定檢查點(diǎn)而停頓。加入檢查點(diǎn)每100個(gè)請(qǐng)求產(chǎn)生一次,k的取值可以是200。
4.4 視圖變更,改朝換代
使用計(jì)時(shí)器的超時(shí)機(jī)制觸發(fā)視圖變更事件
視圖變更協(xié)議在主節(jié)點(diǎn)失效的時(shí)候仍然保證系統(tǒng)的活性。視圖變更可以由超時(shí)觸發(fā),以防止備份節(jié)點(diǎn)無期限地等待請(qǐng)求的執(zhí)行。備份節(jié)點(diǎn)等待一個(gè)請(qǐng)求,就是該節(jié)點(diǎn)接收到一個(gè)有效請(qǐng)求,但是還沒有執(zhí)行它。當(dāng)備份節(jié)點(diǎn)接收到一個(gè)請(qǐng)求但是計(jì)時(shí)器還未運(yùn)行,那么它就啟動(dòng)計(jì)時(shí)器;當(dāng)它不再等待請(qǐng)求的執(zhí)行就把計(jì)時(shí)器停止,但是當(dāng)它等待其他請(qǐng)求執(zhí)行的時(shí)候再次情動(dòng)計(jì)時(shí)器。
作者:李啟雷
鏈接:http://www.jianshu.com/p/fb5edf031afd
來源:簡(jiǎn)書
著作權(quán)歸作者所有。商業(yè)轉(zhuǎn)載請(qǐng)聯(lián)系作者獲得授權(quán),非商業(yè)轉(zhuǎn)載請(qǐng)注明出處。
總結(jié)
以上是生活随笔為你收集整理的区块链核心技术:拜占庭共识算法之PBFT全面理解的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Hyperledger Fabric1.
- 下一篇: 一图简述大数据技术生态圈