區塊鏈系統,首先是一個分散式系統。

從傳統的集中式單節點結構,演變到分散式多節點結構,碰到的首個問題就是一致性的保障。本文將介紹分散式系統領域中兩個很基礎的概念:一致性和共識性。包括兩者的定義,分類,區別與聯繫等等。全文按照如下結構展開:

全文結構


1、一致性

一致性問題是分散式領域最為基礎也是最重要的問題。

如果分散式系統能實現「一致」,對外就可以呈現為一個完美的、可擴展的「虛擬節點」,相對物理節點具備更優越性能和穩定性。這也是分散式系統希望能實現的最終目標。那麼,讓我們來看看「一致性」的定義和性質是什麼吧!


一致性的定義

在分散式系統中,運行著多個相互關聯的服務節點。

一致性是指分散式系統中的多個服務節點,給定一系列的操作,在約定協議的保障下,使它們對外界呈現的狀態是一致的。換句話說,也就是保證集羣中所有服務節點中的數據完全相同並且能夠對某個提案(Proposal)達成一致

在學習過程中,一度被分散式事務一致性分散式數據一致性這兩種說法搞混淆。實際上,兩者是從兩種不同的角度對一致性的描述。

在這裡,事務(資料庫事務的簡稱)是資料庫管理系統中執行過程中的一個邏輯單位,由一個有限的資料庫操作序列構成。分散式事務一致性,指的是「操作序列在多個服務節點中執行的順序是一致的」。分散式數據一致性,指的是「數據在多份副本中存儲時,各副本中的數據是一致的」。保證了分散式事務的一致性,也就保證了數據的一致性。


一致性的要求

在分散式系統中,要達成的一致性,需要滿足哪些要求呢?

  • 首先,達成一致的結果在有限的時間內完成。簡稱為有限性
  • 其次,不同節點最終完成決略的結果是相同的。約同性
  • 決策的結果必須是系統中某個節點提出來的。合法性

也就是說,在分散式系統中,如果一個由節點提出的提案,能夠用在有限的時間內,達到一致性的結果,我們就說該提案達到了一致性。


一致性的分類

一般來講,分散式系統中的一致性(strong consistency)按照對一致性要求的不同,主要分為,嚴格一致性,強一致性,弱一致性和最終一致性這四大類。接下來按照這個下圖架構一一說明:

  • 嚴格一致性

在分散式系統中,有一種理想狀態的「嚴格一致性」。

嚴格一致性的標準是,對於數據項x的任何讀操作將返回最近一次對x進行的寫操作的結果所對應的值。

嚴格一致性中存在的問題是它依賴於絕對的全局時間。對於所有的進程來說,所有寫操作都是瞬間可見的,系統維持著一個絕對的全局時間順序。如果一個數據項被改變了,那麼無論數據項改變之後多久執行讀操作,無論哪些進程執行讀操作,無論這些進程的位置如何,所有在該數據項上執行的後續讀操作都將得到新數值。

嚴格一致性,是在系統不發生任何故障,而且所有節點之間的通信無需任何時間這種理想的條件下,才能達到。這個時候整個系統其實就等價於一臺機器了。在現實中,是不可能達到的。

實際上,越強的一致性要求往往會造成越弱的處理性能,以及越差的可擴展性。

  • 強一致性

當滿足強一致性時,滿足如下要求:

當分散式系統中更新操作完成之後,任何多個進程或線程,訪問系統都會獲得最新的值。

一般來講,強一致性(strong consistency)主要包括下面兩類

    • 順序一致性
    • 線性一致性

順序一致性是指任何執行結果都是相同的,就好像所有進程對數據存儲的讀、寫操作是按某種序列順序執行的,並且每個進程的操作按照程序所指定的順序出現在這個序列中 。

順序一致性的介紹比較抽象,這裡舉一個例子來說明。

例子摘自:並行編程——內存模型之順序一致性 假設我們有兩個線程(線程1和線程2)分別運行在兩個CPU上,有兩個初始值為0的全局共享變數x和y,兩個線程分別執行下面兩條指令:初始條件: x = y = 0;

因為多線程程序是交錯執行的,所以程序可能有如下幾種執行順序:

當然上面三種情況並沒包括所有可能的執行順序,但是它們已經包括所有可能出現的結果了,所以我們只舉上面三個例子。我們注意到這個程序只可能出現上面三種結果,但是不可能出現r1==0 and r2==0的情況。

所謂的順序一致性,其實就是規定了一下兩個條件:

(1)每個線程內部的指令都是按照程序規定的順序(program order)執行的(單個線程的視角)

(2)線程執行的交錯順序可以是任意的,但是所有線程所看見的整個程序的總體執行順序都是一樣的(整個程序的視角)第一點很容易理解,就是說線程1裡面的兩條語句一定在該線程中一定是x=1先執行,r1=y後執行。第二點就是說線程1和線程2所看見的整個程序的執行順序都是一樣的。舉例子就是假設線程1看見整個程序的執行順序是我們上面例子中的Execution 1,那麼線程2看見的整個程序的執行順序也是Execution 1,不能是Execution 2或者Execution 3。

總結下來,順序一致性,要求所有線程所見的整個程序的總體執行順序是一樣的。也就是說,順序一致性保證的是對一系列地址訪問的一致性。

順序一致性實際上限制了各進程內指令的偏序關係,但不在進程間按照物理時間進行全局排序

線性一致性假設操作具有一個全局有效時鐘的時間戳,但是這個時鐘僅具有有限的精確度。要求時間戳在前的進程先執行。線性化是根據一系列同步時鐘確定序列順序的 。

  • 弱一致性

弱一致性是指系統並不保證後續進程或線程的訪問都會返回最新的更新的值。系統在數據成功吸入之後,不承諾立即可以讀到最新寫入的值,也不會具體承諾多久讀到。但是會儘可能保證在某個時間級別(秒級)之後。可以讓數據達到一致性狀態。也就是說,如果能容忍後續的部分或者全部訪問不到,則是弱一致性。

  • 最終一致性

最終一致性是弱一致性的特定形式。系統保證在沒有後續更新的前提下,系統最終返回上一次更新操作的值。 也就是說,如果經過一段時間後要求能訪問到更新後的數據,則是最終一致性。

在最終一致性的要求下,如果沒有故障發生,不一致窗口的時間主要受通信延遲,系統負載和複製副本的個數影響。DNS是一個典型的最終一致性系統。


2、共識性

共識性的定義

共識性描述了分散式系統中多個節點之間,彼此對某個狀態達成一致結果的過程。 在實踐中,要保障系統滿足不同程度的一致性,核心過程往往需要通過共識演算法來達成。

共識演算法

共識演算法解決的是對某個提案(proposal)大家達成一致意見的過程。提案的含義在分散式系統中十分寬泛,如多個事件發生的順序、某個鍵對應的值、誰是領導……等等。可以認為任何可以達成一致的信息都是一個提案。對於分散式系統來講,各個節點通常都是相同的確定性狀態機模型(又稱為狀態機複製問題,state-machine replication),從相同初始狀態開始接收相同順序的指令,則可以保證相同的結果狀態。因此,系統中多個節點最關鍵的是對多個事件的順序進行共識,即排序。

根據解決的是非拜占庭的普通錯誤情況還是拜占庭錯誤情況,共識演算法可以分為Crash Fault Tolerance(CFT)類演算法和Byzantine Fault Tolerance(BFT)類演算法。

  • 非拜占庭容錯類演算法

針對常見的非拜占庭錯誤的情況,已經存在一些經典的解決演算法,包括Paxos、Raft及其變種等。這類容錯演算法往往性能比較好,處理較快,容忍不超過一半的故障節點。

  • 拜占庭容錯類演算法

對於要能容忍拜占庭錯誤的情況,一般包括PBFT(Practical Byzantine Fault Tolerance)為代表的確定性系列演算法、PoW為代表的概率演算法等。對於確定性演算法,一旦達成對某個結果的共識就不可逆轉,即共識是最終結果;而對於概率類演算法,共識結果則是臨時的,隨著時間推移或某種強化,共識結果被推翻的概率越來越小,成為事實上的最終結果。

拜占庭類容錯演算法往往性能較差,容忍不超過1/3的故障節點。此外,XFT(Cross Fault Tolerance)等最近提出的改進演算法可以提供類似CFT的處理響應速度,並能在大多數節點正常工作時提供BFT保障。


3、共識性與一致性的區別

一致性往往指分散式系統中多個副本對外呈現的數據的狀態。如前面提到的順序一致性、線性一致性,描述了多個節點對數據狀態的維護能力。

共識性則描述了分散式系統中多個節點之間,彼此對某個狀態達成一致結果的過程。

因此,一致性描述的是結果狀態共識則是一種手段達成某種共識並不意味著就保障了一致性(這裡的一致性指強一致性)。只能說共識機制,能夠實現某種程度上的一致性。

實踐中,要保障系統滿足不同程度的一致性,核心過程往往需要通過共識演算法來達成。

4、總結

通過這篇文章的學習,我們知道了分散式系統中兩個重要的基礎概念,一致性與共識性,包括他們的分類,特點等等。這對我們理解後面的各種共識演算法和分散式系統理論非常重要。

參考文章:

關於分散式一致性的探究

分散式系統事務一致性解決方案

《區塊鏈原理,設計與應用》-楊保華、陳昌-第四章-分散式系統核心問題

推薦閱讀:

相關文章