這個小姐姐說:你以前所知道的區塊鏈可能都是錯的

image

隨着幣價的一直下跌,有傳言說,比特幣價格這次崩盤,只是大 BOSS 吳忌寒爲加速淘汰老舊礦機而祭出的絕招。git

不管這個陰謀論真假與否,在整個區塊鏈行業的凜冽寒冬中,價格的漲跌已經左右了太多的人頭腦之中的理智。但是,衆人之中,究竟有幾我的真正理解了區塊鏈技術的密碼學機制與分佈式計算?究竟有幾我的還會關心區塊鏈在技術上的創新?github

塵歸塵,土歸土。可能只有巨大的泡沫消散以後,區塊鏈才能經過技術創新顯示出真正的影響力。讓區塊鏈迴歸技術與應用的本質,這也是咱們一直以來的定位。然而,傳播這樣的內容和話題,離不開貨真價實的技術乾貨,以及有感染力的人物和故事。算法

咱們今天的內容就來自於這樣一個女生:數據庫

她是工業與系統工程專業出身,作過頂級投行高盛的分析師,作過著名風投 a16z 的合夥人——這都是許多人求之不得的工做。可是,功成名就的路上,她卻發現編程纔是本身想要的生活。編程

image

笨辦法學會編程?她沒學會。如何用 HTML/CSS 作一個網頁?她開始上癮了。因此,沒有選擇斯坦福、MIT 的編程學位,她更喜歡 Hack Reactor 的全棧動手實踐。先學 JavaScript、React,後面的想法是機器學習、計算機視覺……這個女生就是 Preethi Kasireddy。安全

接觸區塊鏈以後,金融從業背景和全棧編程能力讓 Preethi 更加如魚得水。從 Coinbase 工程師到智能合約設計的自由職業者,究根問底的天性讓她開始用最淺顯易懂的語言來向你們解釋區塊鏈技術的真相,篇篇爆款:網絡

好比這篇,《最全!寫給技術小白的以太坊完整工做原理和運行機制!》,原文 「How does Ethereum work, anyway?」 在 Medium 獲贊 45000+。架構

https://medium.com/@preethikasireddy/how-does-ethereum-work-anyway-22d1df506369併發

好比這篇,《公有鏈的基本挑戰》,原文 「Fundamental challenges with public blockchains」 在 Medium 獲贊 17200+,評論比原文還長。機器學習

https://medium.com/@preethikasireddy/fundamental-challenges-with-public-blockchains-253c800e9428

好比這篇,《區塊鏈尚沒法擴展,至少如今不成,但但願猶在》,原文 「Blockchains don’t scale. Not today, at least. But there’s hope.」 在 Medium 獲贊 13600+,由技術專欄 「Hacker Noon」 特別約稿。

https://medium.com/@preethikasireddy/why-im-leaving-silicon-valley-72919edb3297

可是,不瞭解分佈式系統的工做原理,不瞭解人們如何能在分散的網絡上達成共識,你始終沒法真正理解區塊鏈技術的創新之處。衆所周知,密碼學和分佈式計算都不是什麼新鮮事物;那爲何把它們整合在一塊兒的區塊鏈技術,卻可以迫使科學家和工程師不得不去從新審視分佈式計算的基本範式呢?

接下來,咱們就聽 Preethi 從分佈式系統的基本概念提及,一步一步說到公式算法,特別是中本聰共識的真正精妙之處,進而抓住區塊鏈技術不會隨泡沫而飄散的真實內涵:

image

分佈式系統其實不是一個新鮮的話題,有關這個課題的研究已經進行過幾十年了。

隨着比特幣、區塊鏈等話題在網絡上風生水起,分佈式系統也逐漸走進大衆的視野。區塊鏈始於比特幣,它自己就是一種新型的分佈式系統,它們的流行反過來又促使分佈式計算領域的研究發生翻天覆地的變化。

想真正弄懂區塊鏈,充分理解分佈式系統是必不可少的。

那麼,你又該如何去了解分佈式系統呢?

這個話題很難三言兩語說清楚,由於它所涉及的知識實在是太普遍、太瑣碎了。關於分佈式計算的資料文獻要麼晦澀難懂,要麼不成體系。何況,隨着應用場景不斷拓展,分佈式系統又衍生出數百種不一樣架構,分別服務於數百種不一樣的需求,這一切讓整個問題愈顯複雜。

而如何把複雜的問題簡單化,把生僻的話題講明白,也就難上加難了。因此,在區塊鏈概念滿天飛的今天,如何 Get 到分佈式系統和共識機制的基本概念而不被忽悠,就顯得越發迫切了。

本文正是出於這樣的目的來介紹入門區塊鏈的這一基礎:

1、什麼是分佈式系統?

2、分佈式系統的基本性質

3、分佈式系統中的共識問題

4、一些基本的共識算法(Paxos、Raft、DLS 和 PBFT)

5、中本聰共識爲何這麼牛?

請記住,若是讀讀這篇文章,你就想成爲行業大拿,這肯是不現實的。

1

什麼是分佈式系統?

分佈式系統是一組不一樣、分散的的進程,它們之間可以互相協調,經過相互間的信息傳遞完成一個共同的目標。儘管這些進程是分開的,但呈現給用戶的,是一個系統、一個總體。

分佈式系統是圍繞同一個目標而協同工做的一羣計算設備。

進程能夠是「節點」、「個體」、「計算機」或「組件」,在本文中,它們的意思都是同樣的。與之相似,「網絡」與「系統」表達的也是同一個意思。

前文中說過,分佈式系統有數百種體系結構。

例如,一臺計算機能夠看做成一個分佈式系統——CPU、內存 和 IO 設備都是獨立的進程,它們相互協做完成同一個目標,好比上網、編程、遊戲。

再好比,下圖中飛機也能夠看作是一個分佈式系統,各單元共同協做,實現飛機的空間轉移。

image

https://www.weetech.de/en/news-info/tester-abc/distributed-system-1/

相似的例子不勝枚舉,在本文中,咱們主要討論進程是獨立分散的計算機的分佈式系統。

image

2

分佈式系統的基本性質

分佈式系統有一些基本的共性,它們包括:

2.1 併發性

系統中的進程是同時操做的,多個事件同時發生。換言之,網絡中的每臺計算機都在同時、獨立地執行任務。

最大的難題在於協調。

image

Lamport, L (1978). Time, Clocks and Ordering of Events in a Distributed System

2.2 缺乏全局時鐘

在分佈式計算機系統中,咱們須要肯定事件發生的前後順序,但因爲各臺計算機在空間上是分開的,因此,咱們缺乏一個全局時鐘。

在《分佈式系統中的時間、時鐘和事件順序》這篇論文中,Leslie Lamport 展現了他的排序方法,首先須要記住如下兩點:

  • 消息發送在收到以前。

  • 每臺計算機都有一系列的事件。

經過肯定某兩個事件的前後,咱們能夠知道系統中事件的部分順序。

譯註:部分順序——對應於整體順序,例如:三個事件的特定順序是 A>B>C,在一次計算中,咱們只要求 A>C,不在意 B 什麼時候發生,這就是部分順序,那麼 A > B > C, A > C > B 和 B > A > C 都知足部分順序。

Lamport 的論文中闡述了一種算法,它要求每臺計算機都能從另外一臺上收到信息。經過這種方式,獲得部分順序後,整體順序也能夠逐步推出來。

在這裏,咱們是徹底根據每臺計算機收到信息的時間來排序的,那就會產生一些異常情況。由於各地的時鐘或多或少都會有差異,這就致使系統順序與外部用戶感知到的順序是不一樣的。

爲了處理這種異常,Lamport 想出一個辦法,同步各地的物理時鐘!

問題這樣就能解決了嗎?太天真了,年輕人!

同步大量獨立的時鐘毫不是一個簡單的事情,而是一個很是複雜的計算機科學問題。即便你在最初精確地設置了一大堆時鐘,因爲時鐘漂移的存在,隨着時間推移,時鐘必定會有所變化。

譯註:時鐘漂移——各個時鐘的計時速度存在細微差異,隨着時間推移,一個時鐘的運行速度與其參考時鐘不徹底相同,失去同步。計算機中使用的以晶體爲基礎的時鐘也會發生漂移。容易被定時攻擊所利用。

所以,在分佈式計算機系統中,時間和事件順序是根本障礙。

2.3 獨立進程故障

在分佈式系統中,每一個進程均可能發生故障,這些故障多是進程崩潰或失控,多是信息遺漏、歪曲或重複,也多是惡意信息,還多是網絡延遲、斷網斷電。

單個進程的故障率其實很低,但隨着系統中的進程愈來愈多,系統會發生故障就從一個偶然事件變爲必然事件。咱們要作的就是開發分佈式協議,保證系統在各類異常情形下仍能正常工做。所以分佈式系統也被稱爲「容錯分佈式計算」。

這些異常可大體分爲三個類型:

  • 崩潰:進程在沒有任何警告的狀況下中止工做,如計算機崩潰。屬於非惡意行爲。

  • 遺漏:進程發送消息,但其餘節點收不到,如消息丟失。屬於非惡意行爲。

  • 拜占庭:進程的行爲隨機。若是是在受控環境(例如 Google 或 Amazon 的數據中心)中,這種狀況能夠不作考慮。咱們主要關心故障發生在「衝突地帶」中的情形,他們的行爲至關隨意,可能會惡意更改和阻斷信息,或者根本就不發送。屬於惡意行爲。

爲了控制網絡中的分散個體,咱們須要設計一項協議,讓必定會產生異常的系統仍然可以提供服務,完成共同目標,即系統須要具有容錯性。

所以,在構建分佈式系統時必須作的核心假設是,在部分異常時系統還可否正常工做,異常是因爲非惡意行爲仍是惡意行爲。

通常來講,在構建分佈式系統時,有兩種模型須要考慮:

(1)簡單容錯

在簡單的容錯系統中,咱們假設系統的全部進程的行爲方式都是固定的:要麼遵照協議,要麼失敗。這種類型的系統可以妥善處理脫機或故障節點,而且沒必要擔憂節點發出任意或惡意的行爲。

可是,若是運行環境不受控,簡單容錯機制很難發揮做用。

(2a)拜占庭容錯

在拜占庭容錯系統中,咱們假設節點可能產生故障或者惡意。在分散系統中,網絡是開放的、不受限制的,節點由獨立的個體控制,所以行爲有很大的隨意性,在設計系統模型時,這種狀況必須考慮。

(2b)BAR 容錯

還有一種故障叫作「理性」故障,即節點爲了自身利益,可能會背離系統總體的目標。換句話說,節點能夠老實,也能夠不老實,這取決於其動機。若是「籌碼」足夠高,那麼甚至大多數節點都會「叛變」。正所謂忠誠,取決於背叛的籌碼。

這被正式定義爲 BAR 模型,它考慮到了拜占庭式故障和理性故障。BAR 模型假設系統中有三種角色:

  • 拜占庭節點:是惡意的,只想做惡 ——壞人

  • 無私節點:誠實的,老是遵循協議 ——老實人

  • 理性節點:符合自身利益纔會遵循協議 ——普通人

2.4 信息傳輸

分佈式系統中的計算機之間經過「信息傳輸」實現溝通和協調,信息傳輸協議能夠任選,不管是 HTTP、RPC 仍是特定場景中的自定義協議。

咱們首先來了解一下信息傳輸環境:

(1)同步式

在同步信息傳輸系統中,假定信息傳輸時間是固定的、已知的。

概念上並不複雜,用戶發送了消息,接收組件就會在固定的時間內獲得消息。這樣用戶能夠根據信息傳輸所需的固定時間上限來設計他們的協議。

然而,在分佈式系統的實際操做中,這種傳輸環境應用有限。由於計算機可能崩潰或掉線,消息可能丟失、重複、延遲或亂序。

(2)異步式

在異步信息傳輸系統中,假定網絡可能無限延遲消息的發送,或者大量重複或者亂序。這時候,對於信息傳輸所需時間是不肯定的。

3

分佈式系統中的共識問題

到這裏,咱們已經瞭解了分佈式系統的下列特性:

  • 併發性                          

  • 缺乏全局時鐘  

  • 獨立進程故障

  • 信息傳輸

接下來,咱們將重點理解在分佈式系統中「達成共識」的意義。最多見的一種模型稱爲複製狀態機。

複製狀態機(Replicated state machine)

複製狀態機,通俗點講,就是多個節點從相同的初始狀態開始,執行相同的一串命令,產生相同的最終狀態。這一系列節點的狀態都是相同的,就是所謂的「複製狀態」。

image

在複製狀態機中,若是某一事務是有效的,將其輸入將致使系統的狀態向下一個轉換。在每一個狀態轉換過程當中,每一個進程決定下一個輸出值。

從一個有效狀態轉換到下一個有效狀態的邏輯稱爲「狀態轉換邏輯」。

image

事務是數據庫上的原子操做,這種操做一旦開始,就一直運行到結束,中間不會有任何切換。

換句話講就是操做要麼徹底完成,要麼根本不發生。在複製狀態機中,這一系列被維護的事務集合稱爲「事務日誌」。

所謂的「達成共識」意味着全部的計算機必須一致贊成在每一個狀態轉換過程當中的輸出值,也就是說,每臺計算機上的事務日誌都是相同的。

複製狀態是一種肯定性狀態機,功能與單個狀態機相同,狀態機中的單個計算機可能發生故障,但整個狀態機依然會正常運轉。

故障主要有:

  • 計算機崩潰。

  • 網絡不穩定,信息傳遞可能會延遲、亂序或者失敗。

  • 沒有全局時鐘,事件順序難以肯定。

即便是在局部故障的狀況下,複製狀態機仍然必須不斷地接受新事務到事務日誌,從而提供服務。這其實也是每一種共識算法的基本目標。

image

共識問題的定義

若是一個算法知足如下條件,它就會達到共識:

  • 一致性:全部非故障進程必須決定相同的輸出值。

  • 終止性:全部非故障節點最後必須在某個值上終止,不能無限循環下去。

注意:不一樣的算法有不一樣的條件。例如,有些算法將一致性劃分爲穩定性和總體性,還有些算法具備合法性、完整性或高效性的概念。在這裏,如此細微的差異,就不贅述了。

在共識算法中,系統中的進程分別擔任這三種角色:

  • 提議者(Proposers)——也稱做領導者(Leader),發出請求或信息

  • 決策者(Acceptors)——接收提議者的請求,輸出響應值的進程

  • 學習者(Learners)——系統中的其餘進程,得到系統決定的終止值

image

定義一個共識算法的過程,一般有如下三個步驟:

第一步,選擇

  • 在全部進程中選擇一個領導者。

  • 領導者提出下一個有效的輸出值。

image

第二步,投票

  • 無端障的進程接收領導者的輸出值,通過驗證,把它看成下一個有效值提出。

image

第三步,決策

  • 全部非故障的進程必須達成共識,以此決定正確的最終值,具體根據全部進程的投票數是否達到預設值。

  • 不然,重複步驟1、2、三,再來一次。

image

image

這裏須要注意,各類共識算法在一些細節上有所區別,好比:

  • 術語(例如:回合、階段、輪次)

  • 處理投票的程序

  • 決定最終值的標準(例如:有效性條件)

上面是共識算法定義的通常過程,知足定義中的通常條件,咱們就能夠構建一種算法,從而建立一個可以達成共識的分佈式系統。

好像很簡單的樣子,有木有?

FLP 不可能性(FLP impossibility)

還差得遠呢,咱們要面對的最大的難題就是——FLP 不可能性(FLP impossibility)

首先回顧一下同步系統和異步系統的區別:

  • 同步環境——信息傳輸所用時間是固定的

  • 異步環境——信息傳輸所用時間沒法預估

這個區別很重要。

在同步環境中,咱們能夠設定信息傳輸所需的最大時間,容許系統中的不一樣節點輪流提出新的事務,而後投票肯定一項,跳過沒有提出事務的節點。這種環境中,達成共識是可能的。

可是,若是想在同步環境中操做,就須要一個信息風險可控的環境,好比說在一個配備原子鐘的數據中心,現實中很難操做。

原子鐘:一種高精度計時裝置,利用原子吸取或釋放能量時發出的電磁波來計時,精度可達每 2000 萬年偏差 1 秒。

然而異步環境中,信息傳輸時間是不固定的,若是有某個進程出故障的話,實現終止將很是困難。

這種狀況,被正式稱爲**「FLP 不可能性結果」。**

其中,FLP 是 Fischer、Lynch、Patterson 這三位學者名字組合的簡寫。

他們在 1985 年發表過這樣一篇論文——《分佈式共識的達成毀於一個出錯的進程》,論文指出——在一個異步系統中,即便只有一個進程出錯,那麼分佈式共識就沒法達成。由於進程出錯的時間是隨機的,若是恰巧在共識達成的時候,那麼就枉費工夫了。

image

對於分佈式計算領域來講,這無疑使人沮喪。儘管如此,科學家們仍在繼續努力尋找規避 FLP 不可能性的方法。目前有兩種:

  • 方法一:使用同步假設

  • 方法二:使用不肯定性

方法一:使用同步假設

FLP 不可能性原理代表,在異步傳輸系統中,若是一個系統沒法終止,那麼就不能達成共識。

可是,若是不知道異步信息傳輸所需的時間,那該如何保證每一個非故障進程都會決定一個輸出值呢?

須要明確的是,這一發現並不表明共識沒法達成,而是在異步傳輸環境中不能在固定的時間內達成。那就是說共識在某些時段仍是能夠達成的,只不過咱們沒法肯定這個時間點。

解決這個問題的一種方法是使用超時。若是系統遲遲沒法在一個值上終止,就等待一個超時,而後從新開始一輪運算。

這須要一些共識算法來支撐,其中的比較出名的是 Paxos 和 Raft。

4

一些基本的共識算法(Paxos、Raft、DLS 和 PBFT)

Paxos算法

Paxos 是由 Leslie Lamport 在上世紀 90 年代提出的,這是第一個實用的容錯共識算法,它已被谷歌和亞馬遜(Amazon)等互聯網巨頭用於構建分佈式服務。

Paxos 的工做機制以下:

階段1:準備請求(prepare request)

  • 提議者選擇一個新的提議版本號 n,而後向決策者發送 「prepare request」。

  • 若是決策者接收到這個 prepare request(「prepare」,n),若是 n 大於任何他們已經迴應過的 prepare request 的版本號,決策者就會發出 (「ack,」 n, n’, v’) 或 (「ack,」 n, ^ , ^)。

  • 決策者的答覆是保證不接受任何版本號小於 n 的提議。

  • 決策者把已接收到的最高版本號的提議中的值 v 做爲建議值。不然,他們用 ^ 迴應。

階段2:接受請求( accept request )

  • 若是提議者接收到多數決策者的響應,那麼它能夠發出一個 accept request (「accept,」 n, v),其編號爲 n,值爲 v。

  • n 是 prepare request 中出現的數字。

  • v 是響應中編號最高的提議中的值。

  • 若是決策者接收到 accept request (「accept,」 n, v),則它經過該提議,除非它已經響應了一個大於 n 的 prepare request。

階段3:學習階段

  • 當決策者經過一個提議時,它會對全部學習者進行響應 (「accept,」 n, v)。

  • 學習者收到大多數決策者發出的 (「accept,」 n, v),就會以 v 爲最終決定值,並把 (「accept,」 n, v) 通知到全部其餘的學習者。

  • 學習者收到 (「accept,」 n, v),把 v 做爲最終決定值。

image

https://www.myassignmenthelp.net/paxos-algorithm-assignment-help

講到這裏,相信不少同窗應該已經懵逼了,可是先別急,更讓人懵逼的可能還在後頭。

咱們都知道,每一個分佈式系統都會有發生異常。在這種算法中,若是提議者因爲信息丟失等緣由出錯,那麼最終決定可能會被延遲,Paxos 算法在第一階段中使用了一個新版本號,來避免以前的計算產生的影響。

Paxos 確實有些難以理解,許多操做細節都沒有解釋透徹。怎樣知道提議者出錯的時間點?什麼時候從新開始下一輪計算?想肯定這些時間點咱們是否須要一個同步時鐘來設置超時時間?這些問題,都須要咱們去思考。

此外,爲了在實際應用中更加靈活,Paxos 關鍵領域的很多規範都是開放式的。諸如領導者選擇、故障檢測和日誌管理等概念都比較模糊或徹底沒有定義。

這樣的設計理念成爲 Paxos 最大的不足之一,理解難、實現難,駕馭分佈式系統更難。

在 Paxos 中,雖然超時在算法中沒有明確說起,但在實際操做中,想要實現終止,等待一個超時後,必須選擇一個新的提議者。不然,決策者就不會輸出下一個值,整個系統就中止了。

Raft算法

2013 年,Ongaro 和 Ousterhout 發佈了一種新的共識算法,用於叫作 Raft 的複製狀態機,主要注重協議的實用性和可理解性。

Raft 算法主要有兩個過程,一個是領導者選舉,另外一個是日誌複製。系統中的節點被分爲三種角色:

  • 領導者——負責與用戶溝通和日誌複製

  • 跟隨者——被動響應請求,相似於選民

  • 候選者——臨時角色,某節點想成爲領導者,就要發起投票請求,同時本身變成候選者。若是選舉成功,則成爲領導者,不然退回爲跟隨者。

這三種角色都不是固定的,能夠隨着環境條件互相轉換,可是在某一個時刻只能擔任其中一種。

爲了實現共識,候選者須要向跟隨者發出信息,請求他們的投票,一旦被系統中大多數承認選定後,就成爲領導者,跟隨者們就跟隨其操做。

假設系統中的節點總數爲 n,故障節點爲 x,正常節點只須要比故障節點多一個,即 x+1,系統就能達成共識。

所以,Raft 算法支持的最大故障節點數量是(n-1)/2。

Raft 算法的容錯機制只支持故障節點,不能支持惡意節點,而且使用共享超時來實現終止。

若是進程崩潰並從新啓動,在聲明本身的領導者身份以前,至少須要等待一個超時時間,並保證會取得進展。

Paxos 和 Raft 是比較傳統的共識算法,它們可以使用同步假設(即超時)在異步環境中一展身手,它們只對崩潰故障容錯,面對拜占庭故障無能爲力。

崩潰故障是更容易把控的,由於程序沒法進行惡意行爲。咱們能夠將進程建模,以 0 或 1 表明正常或崩潰。所以,在崩潰容錯系統中,只要大多數進程可以達成共識,就能夠構建分佈式系統。

而在開放和分散的系統(如公鏈)中,網絡中的節點是不受用戶控制的,節點有不一樣的動機,能夠撒謊、配合或爲所欲爲,一半以上的可靠節點能夠約定好互相撒謊,互相之間必然發生衝突。

因此在拜占庭系統中,不是假設簡單多數就能夠達成共識的。

對於這種行爲,Raft 應對乏力。舉例來講,若是選出來的領導者是拜占庭節點,而且與其餘節點有着緊密的聯繫,那麼系統就危險了。以前講過,咱們創建的系統模型,要麼對簡單故障容錯,要麼對拜占庭故障容錯。

總之,Raft 和 Paxos 具備簡單的容錯能力,但對拜占庭故障無能爲力。

那麼問題來了,拜占庭環境怎麼辦?!

在解決這個問題以前,咱們先來了解一個概念——

拜占庭將軍問題(Byzantine Generals Problem)

拜占庭將軍問題由 Leslie Lamport、Robert Shostak 和 Marshall Pease 在同名論文中提出,分佈式系統依靠交換信息來總體協做,然而其中的節點會做惡,網絡會崩壞,所以系統不能達成一致。

拜占庭容錯協議就是爲了應對節點的惡意行爲,論文爲解決拜占庭將軍問題提供了第一個證實:

若是一個系統共有 n 個節點,其中有 x 個是拜占庭節點,該系統若是想達成共識,n 必須知足:n>3x + 1

緣由以下:

若是出錯節點個數爲 x,系統若是想正常運轉,必須先協調的節點個數爲 n - x,(由於 x 個節點可能有問題/複雜,而且沒有響應)。

然而不排除這種可能,不響應的x也許並非出錯了,也多是有響應的只不過因爲網絡等緣由未被察覺。若是咱們想要非故障節點的數量多於故障節點,n 必要知足:

n- x - x > x,

即:n > 3x + 1

然而,該論文所演示的算法僅適用於同步環境,那貌似拜占庭環境、異步環境二者咱們只能解決一個了,或者只能等待奇蹟的發生。

學者們作了大量的研究工做,力求攻破在拜占庭和異步假設環境中的共識問題。

下面即是見證奇蹟的時刻——

我全都想要!!!

接下來,咱們將研究兩種算法(DLS 和 PBFT),打破拜占庭+異步的障礙的奇蹟,咱們在慢慢靠近。

DLS 算法

Dwork、Lynch 和 Stockmeyer(「DLS」算法的由來)在 1988 年曾發表論文《部分同步存在的共識》,文中闡述了關於拜占庭容錯共識的一個重大進展:在「部分同步系統」中達成共識

你可能還記得,在同步系統中,信息從發送到接收所需的時間是有固定上限的,而在異步系統中,該上限不存在。

這裏的「部分同步」位於同步系統和異步系統之間。

本文解釋了部分同步假設的兩個版本:

  • 假設信息傳輸所需的時間上限是存在的,可是是未知的。目標是達成共識,先不考慮實際的上限。

  • 假設信息傳輸所需的時間上限是已知的,可是它只能保證在某個未知的時間(也稱爲「全球標準化時間」,GST)啓動。目標是設計一個可以達成共識的系統,不管這個未知的時間在何時。

如下是 DLS 算法的工做原理:

運算的每一輪都被分爲「試探」階段和「鎖定-釋放」階段。N 是系統的總節點數量,x 是系統的容錯節點數量。

  • 每一輪都有一個提議者,回合的開始時候,每一個進程傳輸各自認爲正確的值。

  • 若是一個值最少被 N − x 個進程程傳達過,那麼提議者將把它做爲建議值。

  • 當某個進程從提議者接收到建議值時,它必須鎖定該值,而後散佈這個信息。

  • 若是提議者接收到 x + 1 個進程發出的建議值,這個值將會做爲最終值提交。

DLS 算法能夠說是一個重大突破,由於它創造了一個新的網絡假設類型,即部分同步,並證實了在部分同步中,實現共識是可能的。

那麼如何實現呢,咱們關注兩點:安全性和活躍性。

安全性

這是「一致性」(Agreement)的另外一個術語。其中全部非故障進程都同意相同的輸出值。若是咱們能保證足夠的安全性,就可以保證整個系統保持同步;而若是安全性不夠,將會致使須要更多的事務日誌來終止這一輪的信息傳輸。咱們但願全部節點都聽從事務日誌的順序,儘管故障和惡意進程是沒法避免的。

活躍性

這是「終止性」(Termination)的另外一個術語。其中每一個非故障節點都會以某個輸出值做爲最終決定值。在區塊鏈設置中,新的區塊不斷生成,區塊鏈不斷延伸,這就是活躍性。只有保持活躍,這個網絡纔有用處,不然,區塊鏈就「爛尾」了。

從 FLP 不可能性中咱們知道,在徹底異步的系統中,共識是不可能達成的。DLS 的論文則認爲,若是進行部分同步假設,就能夠營造活躍環境,而這就足以攻克 FLP 不可能性。

所以,本文證實了該算法無需進行同步假設,安全條件均可以保證。

若是節點沒有決定某個輸出值,系統就會中止。爲了保證終止,也就是保證活躍性,咱們能夠作一些同步假設(即超時)。但若是某一次同步假設失敗,系統也會中止。

可是,若是咱們設計一個算法,在這個算法中假設超時以保證安全性。可一旦若是同步假設失敗,就有可能致使有兩個有效的事務日誌生成。

兩個事務日誌要比系統中止要危險得多——若是不安全,那麼活躍無心義。

能夠說,即便整個區塊鏈中止,那也好過於生成兩個不一樣的區塊鏈。

分佈式系統老是在權衡取捨。若是你想突破一個限制(好比 FLP 不可能性),你必須在別的地方作出讓步。在這種狀況下,把關注點分紅安全性與活躍性是很是合理的。這樣咱們能夠構建一個在異步假設中的安全系統,但仍然須要超時來保證有新的值持續輸出。

DLS 的論文已經講得足夠詳細,但到現在,DLS 從未真正地被普遍應用,甚至沒有在實際的拜占庭場景中使用。這可能由於 DLS 算法的核心假設之一是使用同步時鐘,以便有一個共同的時間概念。實際上,同步時鐘很容易受到多重攻擊,在一個拜占庭容錯假設中每每不夠可靠。

PBFT(Practical Byzantine Fault-Tolerance)

Miguel Castro 和 Barbara Liskov 在 1999 年發表了論文《Practical Byzantine Fault-Tolerance》(《實用的拜占庭容錯》),其中提出了 PBFT 算法。對於拜占庭系統來講,這種算法正如其名——更加「實用」。

這篇論文認爲,之前的算法雖然「理論上可行」,但要麼太慢而沒法使用,要麼爲了安全性必須作同步假設。咱們前文中提過,這在異步環境中是很是危險的。

PBFT 中的 「P」(Practical)意味着該算法能夠在異步環境中應用,而且作了一些優化,運行速度會更快。

在 PBFT 中,不管有多少故障節點,系統都可以提供安全性。若是系統內的節點總數是 n,那麼算法的容錯節點數量 x 的最大值是 (n-1)/3,並且消息延遲的增加速度不會超過必定的時間限制。

所以,PBFT 進行同步假設並非爲了安全,而是爲了活躍,並以此規避 FLP 不可能性。

算法經過一系列「視圖」(view)運行,每一個視圖都有一個「主」節點(即領導者),其他的都是「備份」。下面是 PBFT 詳細的工做步驟:

  • 客戶端有一項新事務,將其發送給主節點。

  • 主節點將這項事務傳遞給全部備份。

  • 各備份執行該事務並向客戶端發送回覆。

  • 客戶端收到來自 x+1 個節點的相同消息後,則該響應就是此次運算的結果,共識已經正確完成。

若是主節點不出錯,協議就能正常運行。然而,若是主節點出錯,或者惡意,備份節點可以經過 timeout 機制檢測到主節點是否已經廢掉。當出現這些異常狀況時,這些備份節點就會觸發視圖更換(view change)協議來選舉出新的主節點。可是這個過程很是緩慢,爲了達成共識,PBFT 須要進行二次通訊——每臺計算機必須與網絡中的全部計算機都進行通訊。

注意:想要完整地解釋PBFT算法,得很是大的篇幅!這裏說一下關鍵部分就好。

雖然 PBFT 相比之前的算法已經有了長足的改進,但對於有大量參與者的實際場景(如公鏈)來講,它還不夠實用。可是,至少在故障檢測和領導者選舉方面,它給出了一些具體的作法,這要比 Paxos 強多了。

PBFT 的貢獻是舉足輕重的,它整合了一系列重要的有變革意義的算法思想,很多新的共識協議從中受益不淺,尤爲是後區塊鏈時代(post-blockchain world)。

好比,Tendermint 是一種新的共識算法,從 PBFT 中獲益頗豐,且設計更加實用。在「驗證」階段,Tendermint 使用兩個投票步驟來決定最終值;Tendermint 每輪都會更換新領導者。若是當前一輪的領導者在一段時間內沒有響應,那麼它就會被跳過,算法直接進入下一輪,併產生新的領導者。而在 PBFT 中,每次視圖更換選新的領導人,都須要一次繁瑣耗時的點對點鏈接,相比起來,Tendermint 運行更簡潔,更有實用意義。

方法一小結

Paxos 和 Raft,具備簡單容錯能力,對系統崩潰或網絡延遲等故障容錯,須要同步信息傳輸環境,適用於嚴格受控的私鏈環境。

DLS 和 PBFT,可對拜占庭故障容錯,在異步信息傳輸環境中須要作某種形式的同步假設(超時),適用於新加入節點須要驗證的聯盟鏈。

方法二:使用不肯定性

下面咱們來介紹另外一種克服 FLP 不可能的方法:不肯定性。所謂不肯定性,就是用機率論和不肯定的方式來解決共識問題。

中本聰共識(Nakamoto Consensus.)

傳統的共識中,算法的定義是這樣的:一個提議者和一羣決策者必須協調和溝通,才能決定下一個值。

這太複雜了,由於它須要知道網絡中的每一個節點,並且各個節點之間都必須溝通,即二次通訊消耗。簡單地說,它的拓展性有限,也不能在開放的、沒有限制的系統中工做,在這種系統中,任何人均可以隨時加入和離開。

中本聰共識使上述的難題成爲機率性的事件,這是其高明之處所在。用不着每一個節點都贊成一個值,只須要全部節點都贊成這個值爲正確的可能性。

咱們從一下幾個板塊來理解:

一、拜占庭容錯機制——工做量證實(PoW,proof of work)

在比特幣網絡中,區塊鏈本質上是去中心化的帳本,用區塊記錄每一筆交易,每一個節點都擁有這個帳本,每一個節點都擁有記帳權。那麼誰來記帳呢?

在中本聰共識中,記帳的節點是不肯定的,哪一個節點解決難題最快,算力最強,它就可以在區塊鏈中添加新區塊。而這個須要節點們去解決的難題也沒有肯定的公式去解決,只能依靠窮舉法。

搶到了記帳權,系統就會告知全網節點,得到全網確認後,這個區塊便會被正式添加,這就是達成共識的過程。

每一個區塊的生成會在區塊鏈上加蓋一個時間戳,網絡就在這個鏈條上延續構建。

規範鏈是指累積了最多工做量,也就是花費了最多的計算量的鏈條,也就是最長的鏈條。它不只能夠證實該鏈堆積了最多的 CPU 算力,還能夠做爲區塊序列的證實。所以,只要大多數 CPU 資源是由誠實的節點掌控的,它們就能繼續生成最長的鏈。

二、區塊獎勵

網絡中的節點經過算力的競爭來爭奪下一個區塊的記帳權,那麼如何使節點們都能心甘情願地消耗巨大的算力去爭奪呢?中本共識的算法設計了區塊獎勵(比特幣),爭奪到記帳權就能夠得到比特幣獎勵,這樣是節點們的目標都能保持一致且相對單純。

三、抵抗女巫攻擊(Sybil Attack)

女巫攻擊:在 P2P 網絡中,節點是能夠隨時加入和退出的。爲了維持網絡穩定,同一份數據一般須要備份到多個分佈式節點上,這就是數據冗餘機制。單個惡意節點假裝多重身份,把原來要備份到多個節點上的數據欺騙到了同一個惡意節點,這種攻擊數據冗餘機制的手段,就叫作女巫攻擊。

中本聰共識採用工做量證實(PoW),節點要證實本身是節點,只能依靠其計算能力,不能依靠分裂或假裝,這樣極大地增長了攻擊的成本。所以中本聰共識自己具備 sybil 抵抗能力,不須要 PKI 或任何其餘花哨的身份驗證方案。

四、點對點流言協議(P2P gossip)

中本聰共識的一個主要貢獻是使用了流言協議(gossip protocol),它更加適合 P2P 網絡環境。在網絡中,一個節點若是想傳遞信息,它會隨機選擇周圍的幾個節點進行散播,收到嘻嘻的節點重複上述過程,最終全網全部節點都能收到信息。簡單的說,就是一傳10、十傳百。

流言協議自己具備分佈式系統的容錯性,由於網絡中任何節點發生故障,都不影響信息傳輸。

在異步環境中「技術上」再也不安全

在中本聰共識中,安全保證是機率性的。新區塊不斷生成,區塊鏈在不斷加長,惡意節點可以創建有效的替代鏈的機率會隨之下降。

機率低不表明不會發生,不是嗎?

因此,中本聰共識在「技術上」並不能保證異步假設中的安全性。這是爲何呢?

由於比特幣區塊鏈中可能存在一個網絡分區,在網絡分區中,若是攻擊者的算力足夠強大,那他就能夠在此分區創建一條比規範鏈還長的「替身鏈」,這樣的話,交易發生所在的規範鏈就可能廢掉,而「替身鏈」成爲主鏈,攻擊者就改變了本身的那筆交易,支付出去的錢又回到了本身手中。

然而,這須要攻擊者得到全網算力的 51%,如此巨大的算力須要耗費鉅額的經濟成本,試問又有誰能承擔得起呢?並且即便攻擊者掌握了 51% 的算力,還須要與另外的 49% 展開 6 次區塊的爭奪,只有連續 6 次成功,才能成功建立「替身鏈」。

從本質上講,「替身鏈」理論上是能夠建立的,可是可能性很是低,這也是前面爲何說「技術上」不安全的緣由。

但這個可能性低到能夠忽略不計,比特幣區塊鏈的不可篡改性就來源於此。

5

中本聰共識爲何這麼牛?

中本聰共識 vs 傳統共識

從實際應用來看,中本聰共識自己是一種拜占庭容錯機制。但很明顯,它並無達到傳統意義上的共識。所以在最初,它被認爲徹底脫離了拜占庭容錯世界。

咱們應當感謝中本聰的這一項偉大創造。

中本聰共識容許任意數量的節點均可以公開參與進來,任意進入,任意退出,並且沒有人必須得知道其餘的參與者都是誰。

中本聰共識比以往的共識算法更簡單,消除了之前算法在點對點鏈接、領導者選舉、二次通訊消耗等方面的複雜性。簡單到在一臺計算機上啓動比特幣協議軟件,就能夠挖礦。

正由於它簡單且有效,因此在現實中有着很廣闊的應用場景,能夠說是 PBFT 的更「實用」的版本。

6

結語

長篇大論以後,前面的一些細節你可能已經忘了,這裏咱們小小總結一下:

這篇文章中,咱們首先介紹了分佈式系統的概念和特性,而後講到了分佈式系統中最重要的問題——如何達成共識。達成共識面臨的最大障礙是FLP不可能性。要跨越這個障礙,咱們有兩種途徑。

第一種是使用同步假設,其中 Paxos 和 Raft 都是在同步環境中,對簡單的故障容錯;而 DLS 和 PBFT 是在異步環境中,使用某種形式的同步假設(即超時),實現都拜占庭故障容錯。

可是在開放(如:公鏈)網絡中,實用性依然有限。

第二種是利用不肯定性。其中中本聰共識是顯著的表明,它給予誠實節點獲利的機會,讓系統達成共識成爲一個機率性(不肯定性)的事件,同時也讓惡意節點形成損害的結果的機率低到能夠忽略不計。適用於節點能夠任意進入和退出的開放式網絡。

讀懂中本聰共識後,區塊鏈技術的其餘進展,咱們也就更容易 Get 到了,好比 POS、Plasma、Casper,等等。Preethi 說她將在下一篇文章中詳解 Proof-of-Steak 的概念和原理,它真的會比中本聰共識更好嗎?

(你沒看錯,是 Proof-of-Steak)

相信這篇長文,會有助於你們來區分區塊鏈領域資本方面的缺點與技術方面的優勢。資本逐利的狂熱總會製造出一些迷惑人的泡沫與假象,但總有一些愛好技術的年輕人,喜歡默默無聞地創新出一些很酷的產品或服務。假以時日,當這些很小的產品或服務長成參天大樹的時候,大多數人才會後知後覺地感覺到——這個世界要變天了!

畢竟,任什麼時候候,肯沉下心來鑽研技術本質的,始終只是那聰明的一小撮人。

參考:

內容來源:區塊鏈大本營(ID:blockchain_camp)

譯者 | 李曉泉

編輯 | 波波

image

相關文章
相關標籤/搜索
本站公眾號
   歡迎關注本站公眾號,獲取更多信息