最近區塊鏈的話題很火。有人想用它改變世界,有人想用它招搖撞騙。html
可是咱們今天只分析技術。從技術的角度看,區塊鏈是一種與分佈式系統有關的技術。它與分佈式系統的各個概念之間有什麼聯繫?今天本文就借這個機會,跟你們一塊兒討論一下分佈式系統的核心問題和概念。最後,咱們將盡可能沿着邏輯上先後一向的思路,討論一下區塊鏈技術。git
一個由區塊鏈技術支撐的系統,好比比特幣網絡或以太坊,從技術上看,是一個很龐大的分佈式系統。所以,咱們首先從分佈式系統開始提及。github
對於技術人員來講,特別是服務器開發人員,幾乎每一個人都常常和分佈式系統打交道。當服務的規模愈來愈大的時候,它必然發展成一個複雜的分佈式系統。很典型的,就是各類分佈式數據庫,它們一般能將數據以某種方式在多個節點上存儲,在高可用的基礎上保證數據的一致性。web
實際上,一致性問題(consensus problem)是分佈式系統須要解決的一個核心問題。分佈式系統通常是由多個地位相等的節點組成,各個節點之間的交互就比如幾我的聚在一塊兒討論問題。讓咱們設想一個更具體的場景,好比三我的討論中午去哪裏吃飯,第一我的說附近剛開了一個火鍋店,據說味道很是不錯;但第二我的說,很差,吃火鍋花的時間過久了,仍是隨便喝點粥算了;而第三我的說,那個粥店我昨天剛去過,太難喝了,還不如去吃麥當勞。結果,三我的僵持不下,始終達不成一致。算法
有人說,這還很差解決,投票唄。因而三我的投了一輪票,結果每一個人仍然堅持本身的提議,問題仍是沒有解決。有人又想了個主意,乾脆咱們選出一個leader,這個leader說什麼,咱們就聽他的,這樣你們就不用爭了。因而,你們開始投票選leader。結果很悲劇,每一個人都以爲本身應該作這個leader。三我的終於發現,「選leader」這件事仍然和原來的「去哪裏吃飯」這個問題在本質上是同樣的,一樣難以解決。數據庫
這時恐怕有些讀者們內心在想,這三我的是有毛病吧......就吃個飯這麼點小事,用得着爭成這樣嗎?實際上,在分佈式系統中的每一個節點之間,若是沒有某種嚴格定義的規則和協議,它們之間的交互就真的有可能像上面說的情形同樣。整個系統達不成一致,就根本無法工做。c#
因此,就有聰明人設計出了一致性協議(consensus protocol),像咱們常見的好比Paxos、Raft、Zab之類。與前面幾我的商量問題相似,若是翻譯成Paxos的術語,至關於每一個節點能夠提出本身的提議(稱爲proposal,裏面包含提議的具體值),協議的最終目標就是各個節點根據必定的規則達成相同的proposal。但以誰的提議爲準呢?咱們容易想到的一個規則多是這樣:哪一個節點先提出提議,就以誰的爲準,後提出的提議無效。可是,在一個分佈式系統中的狀況可比幾我的聚在一塊兒討論問題複雜多了,這裏邊還有網絡延遲的問題,致使你很難對發生的全部事件進行全局地排序。舉個簡單的例子,假設節點A和B分別幾乎同時地向節點X和Y發出了本身的proposal,但因爲消息在網絡中的延遲狀況不一樣,最後結果是:X先收到了A的proposal,後收到了B的proposal;可是Y正好相反,它先收到了B的proposal,後收到了A的proposal。這樣在X和Y分別看來,誰先誰後就難以達成一致了。緩存
此外,若是考慮到節點宕機和消息丟失的可能性,狀況還會更復雜。節點宕機能夠當作是消息丟失的特例,至關於發給這個節點的消息所有丟失了。這在CAP的理論框架下,至關於發生了網絡分割(network partitioning),也就是對應CAP中的P。爲何節點宕機和消息丟失都能歸結到網絡分割的狀況上去呢?是由於這幾種狀況實際上沒法區分。好比,有若干個節點聯繫不上了,也就是說,對於其它節點來講,它們發送給這些節點的消息收不到沒有迴應。真正的緣由,多是網絡中間不通了,也多是那些目的節點宕機了,也多是消息無限期地被延遲了。總之,就是系統中有些節點聯繫不上了,它們不能再參與決策,但也不表明它們過一段時間不能從新聯繫上。安全
爲了表達上更直觀,下面咱們仍是假設某些節點宕機了。那在這個時候,剩下的節點在缺乏了某些節點參與決策的狀況下,還能不能對於提議達成一致呢?即便是達成了一致,那麼在那些宕機的節點從新恢復過來以後(注意這時候它們對於其它節點之間已經達成一致的提議可能一無所知),它們會不會對於已經達成的一致提議從新提出異議,從而形成混亂?全部這些問題,都是分佈式一致性協議須要解決的。服務器
咱們這裏沒有足夠的篇幅來詳細討論這些協議具體的實現了,感興趣的讀者能夠去查閱相關的論文。實際上,理解問題自己比理解問題的答案要重要的多。總之,咱們須要知道的是,咱們已經有了一些現成的分佈式一致性算法,它們能解決上面討論的這些問題,保證在一個去中心化的網絡中,各個節點之間最終可以對於提議達成一致。並且,通常來講,只要網絡中的大部分節點(或一個quorum)仍然存活(即它們相互間能夠收發消息),這個一致性的提議就能夠達成。
咱們前面討論的一致性協議,有一個重要的前提條件,就是:各個節點都是能夠信任的,它們都嚴格遵照一樣的一套規則。這個條件,在一個公司的內部網絡中能夠認爲是基本能知足的。但若是這個條件不知足會怎麼樣呢?假設網絡中有些節點是惡意的,它們不但不遵照協議,還故意搗亂(好比胡亂發送消息),那麼其它正常的節點還可以順利工做嗎?
在分佈式系統理論中,這個問題被抽象成了一個著名的問題——拜占庭將軍問題(Byzantine Generals Problem)。這個問題由大名鼎鼎的Leslie Lamport提出,也就是Paxos的做者。同時,Lamport仍是2013年的圖靈獎得主。
這要從一個故事開始提及(固然這個故事是Lamport編出來的)。拜占庭帝國的幾支軍隊攻打到了敵人的城市外面,而後分開駐紮。每一支軍隊由一位拜占庭將軍(Byzantine general)率領。爲了制定出一個統一的做戰計劃,每一位將軍須要經過信差(messenger)與其它將軍互通消息。可是,在拜占庭將軍之間可能出現了叛徒(traitor)。這些叛徒將軍的目的是阻撓其餘忠誠的將軍(loyal generals)達成一致的做戰計劃。爲了這一目的,他們可能作任何事,好比串通起來,故意傳出虛假消息,或者不傳出任何消息。
咱們來看一個簡單的例子。假設有5位將軍,他們投票來決定是進攻仍是撤退。其中兩位認爲應該進攻,還有兩位認爲應該撤退,這時候進攻和撤退的票數是2:2打平了。第五位將軍剛好是個叛徒,他告訴前兩位應該進攻,但告訴後兩位應該撤退,結果前兩位將軍最終決定進攻,然後兩位將軍卻決定撤退。沒有達成一致的做戰計劃。
這個問題顯然比咱們在前一章討論的可信任環境下的一致性問題要更難。要解決這個問題,咱們是但願能找到一個算法,保證在存在叛徒阻撓的狀況下,咱們仍然可以達成以下目標:
能夠看出,上面的目標A,是比較明確的,至少給定一個算法很容易斷定它有沒有達到這個目標。但目標B卻讓人無從下手。一個做戰計劃是否是「合理」的,原本就很差定義。即便沒有叛徒的存在,忠誠的將軍們也未必就必定能制定出合理的計劃。這涉及到科學研究中一個很是重要的問題,若是一個事情不能用一種形式化的方式清晰的定義出來,對於它的研究也就無從談起,這個事情自己也沒法上升到科學的層面。Lamport在對拜占庭將軍問題的研究中,一個突出的貢獻就是,把這個看似不太好界定的問題,巧妙地歸約到了一個能用數學語言精確描述的問題上去。下面咱們就看一下這個過程是怎麼作的。
首先咱們考慮一下將軍們制定做戰計劃的過程(先假設沒有叛徒)。每一位將軍根據本身對戰局的觀察,給出他建議的做戰計劃——是進攻仍是撤退。而後,每位將軍把本身的做戰建議經過信差傳達給其餘每一位將軍。如今每一位將軍都知道了其餘將軍的做戰建議,再加上他本身的做戰建議,他須要根據全部這些信息獲得最終的一個做戰計劃。爲了表達上更清晰,咱們給每位將軍進行編號,分別是1, 2, ..., n,每位將軍提出的做戰建議記爲v(1), v(2), ..., v(n),一共是n個值,這其中有些表明「進攻」,有些表明「撤退」。通過信差傳遞消息以後,每位將軍都看到了相同的做戰提議v(1), v(2), ..., v(n),固然這其中的一個是當前這位將軍本身提出來的。而後只要每位將軍採用一樣的方法,對全部的v(1), v(2), ..., v(n)這些信息進行彙總,就能獲得一樣的最終做戰計劃。好比,容易想到的一個方法是投票法,即對v(1), v(2), ..., v(n)中不一樣的做戰計劃進行投票,最後選擇得票最多的做戰計劃。
固然,這樣獲得的最終做戰計劃也不能保證就是最好的,但這應該是咱們能作到的最好的了。咱們如今仍然假設將軍裏沒有叛徒。咱們發現,前面提到的目標A和目標B的要求能夠適當「下降」一些:咱們再也不關注將軍們是否能達成最終一致的做戰計劃,而且這個計劃是否是「合理」;咱們只關注每一個將軍是否收到了徹底相同的做戰建議v(1), v(2), ..., v(n)。只要每位將軍收到的這些做戰建議是徹底相同的,他們再用一樣的方法進行彙總,就很容易獲得最終一致的做戰計劃。至於這個最終的做戰計劃是否是最好的,那就跟不少「人爲」的因素有關了,咱們不去管它。
如今咱們考慮將軍中出現了叛徒。遵循前面的思路,咱們仍然但願每位將軍可以收到徹底相同的做戰建議v(1), v(2), ..., v(n)。如今咱們仔細審視一下其中的一個值,v(i),在前面的描述中,它表示來自第i個將軍的做戰提議。若是第i個將軍是忠誠的,那麼這個定義沒有什麼問題。可是,若是第i個將軍是叛徒,那麼就有問題了。爲何呢?由於叛徒能夠隨心所欲,他爲了擾亂整個做戰計劃的制定,徹底可能向不一樣的將軍給出不一樣的做戰提議。這樣的話,不一樣的忠誠將軍收到的來自第i個將軍的v(i)多是不一樣的值。這樣v(i)這個定義就不對了,它須要改一改。
無論怎麼樣,即便存在叛徒,咱們仍是但願每位將軍最終是基於徹底相同的做戰提議來作彙總,這些做戰提議仍然記爲v(1), v(2), ..., v(n)。不過,這裏的v(i)再也不表示來自第i個將軍的做戰提議,而是表示通過咱們設計的某個一致性算法處理以後,每位將軍最終看到的第i個提議。這裏須要分兩種狀況討論。首先第一種狀況,若是第i個將軍是忠誠的,那麼咱們天然但願這個v(i)就是第i個將軍發送出來的做戰提議。換句話說,咱們但願通過一致性算法處理以後,第i個將軍若是是忠誠的,那麼它的提議可以被如實地傳達給其餘將軍,而不會被叛徒的行爲所幹擾。這是可能制定出「合理」做戰計劃的前提。第二種狀況,若是第i個將軍是叛徒,那麼他有可能向不一樣的將軍發送不一樣的提議。這時候咱們不可以只聽他的一面之詞,而是但願通過一致性算法處理以後,各個將軍之間充分交換意見,而後根據其餘各個將軍轉述的信息,綜合判斷獲得一個v(i)。這個v(i)是進攻仍是撤退,並不過重要,關鍵是要保證每位將軍獲得的v(i)是相同的。只有這樣,各位將軍通過彙總全部的v(1), v(2), ..., v(n)以後才能獲得最終的徹底一致的做戰計劃。
根據上面的分析,咱們發現,在這兩種狀況中,咱們都只須要關注單個將軍(也就是第i個將軍)所發出的提議如何傳達給其餘將軍。重點終於來了!至此,咱們就可以把原來的問題歸約到一個子問題上。這個子問題,纔是Leslie Lamport在他的論文中被真正命名爲「拜占庭將軍問題(Byzantine Generals Problem)」的那個問題。在這個問題中,咱們只關注發送命令的單個將軍,稱他爲主將(commanding general),而其餘接受命令的將軍稱爲副官(lieutenant)。下面是「拜占庭將軍問題」的精確描述。
一個主將發送命令給n-1個副官,如何才能確保下面兩個條件:
這其實正好對應了咱們前面已經討論過的兩種狀況。若是主將是忠誠的,那麼條件IC2保證了命令如實地傳遞,這時候條件IC1天然也知足了;若是主將是叛徒,那麼條件IC2沒有意義了,而條件IC1保證了,即便叛徒主將對每一個副官發出不一樣的命令,每一個副官仍然能最終得到一致的命令。
這裏有兩個地方可能讓人產生疑惑。
第一,有些人會問了,難道主將還能是叛徒?主將都是叛徒了,還有啥搞頭啊?實際上是這樣的,這個「拜占庭將軍問題」只是原問題的一個子問題。當n個將軍經過傳遞消息來決策做戰計劃的時候,能夠分解成n個「拜占庭將軍問題」,即分別以每位將軍做爲主將,以其他n-1位將軍做爲副官。若是有一個算法可以解決「拜占庭將軍問題」,那麼同時運行n個算法實例,就能使得每位將軍都得到徹底相同的做戰建議序列,即前面咱們提到的v(1), v(2), ..., v(n)。最後,每位將軍將v(1), v(2), ..., v(n)使用相同的方法進行彙總(好比按多數投票),就能獲得最終的做戰計劃。
第二,當主將是叛徒的時候,他能夠向不一樣的副官發送不一樣的命令,怎麼可能每一個副官仍然能最終得到一致的命令呢?這正是算法須要解決的。其實這也容易解釋(咱們前面也提到過這個思路),因爲主將可能向不一樣的副官發送不一樣的命令,因此副官不能直接採用主將發來的命令,而是也要看看其餘副官轉述來的主將的命令是什麼。而後,一個副官綜合了由全部副官轉述的命令(再加上主將直接發來的命令)以後,就可能獲得比較全面的信息,從而作出一致的判斷(在實際中是個不斷迭代的過程)。
好了,咱們用了這麼多篇幅,終於把「拜占庭將軍問題」自己描述清楚了。這實際上也是最難的部分。咱們上一章提到過,理解問題自己比理解問題的答案更重要。只要問題自己分析清楚了,如何設計一個能解決它的算法就只是細節問題了。咱們這裏不深刻算法的細節了,感興趣的讀者能夠去查閱下列論文:
咱們這裏只提一下論文給出的算法的結論。
使用不一樣的消息模型,「拜占庭將軍問題」有不一樣的解法。
咱們前面提到過,以Paxos爲表明的分佈式一致性協議,是在可信任的環境下運行的。而在「拜占庭將軍問題」中,網絡中則存在惡意節點。所以咱們很容易產生一個想法:Paxos是否是「拜占庭將軍問題」在叛徒數爲零時的一個特例解?
這樣看其實有點問題。在「拜占庭將軍問題」中,除了叛徒,剩下的是忠誠的將軍。「忠誠」這個詞,其實暗含了一個意思:他是可以正常工做的(即你能夠隨時經過消息跟他進行交互)。爲何這麼說呢?咱們知道,一個叛徒能夠作任何事,包括髮送錯誤消息,也包括不發送任何消息。「不發送任何消息」,至關於不能正常工做,或者說,發生了某種故障。因此,單純的故障,不只僅是故意的惡意行爲,也應該能納入叛徒的行爲。這在其餘將軍看來沒有區別。
按照這種理解,「忠誠」這個詞並非很恰當。叛徒數爲零,至關於網絡中每一個節點都在正常工做。可是Paxos的設計也是可以容錯的,就像咱們在前面討論的同樣,網絡中的少數節點發生故障(好比宕機),Paxos仍然能正常工做。可見,Paxos並不能當作是「拜占庭將軍問題」在叛徒數爲零時的一個特例解。
那「拜占庭將軍問題」和Paxos這類分佈式一致性算法的關係應該如何看待呢?咱們能夠從容錯性的強弱程度上來分析。
通常來講,設計一個計算機系統,小到一塊芯片,大到一個分佈式網絡,都須要考慮必定的容錯性(fault tolerance)。但根據錯誤不一樣的性質,能夠分爲兩大類:
這兩類錯誤的含義並無字面上那麼好理解。
先說說拜占庭錯誤。在「拜占庭將軍問題」中,叛徒的惡意行爲當然是屬於這一類錯誤的。在不一樣的將軍看來,叛徒可能發送徹底不一致的做戰提議。而在計算機系統中,出現故障的節點或部件也可能表現出先後不一致的行爲,雖然這並不是惡意,但也屬於這一類錯誤。好比信道不穩定,致使節點發送給其它節點的消息發生了隨機錯誤,或者說,消息損壞了(corrupted)。再好比,在數據庫系統中,commit以後的數據明明已經同步給磁盤了(經過操做系統的fsync),但因爲忽然斷電等緣由,最終數據仍是沒有真正落盤成功,甚至出現數據錯亂。
再看一下非拜占庭錯誤。Lamport在他關於Paxos的一篇論文中也使用了non-Byzantine這個詞(見《Paxos Made Simple》)。可是這個詞的命名的確讓人有點很差理解。在分佈式系統中,若是節點宕機了,或者網絡不通了,都會致使某些節點不能工做。其它節點其實無法區分這兩種狀況,在它看來,只是發現某個節點暫時聯繫不上了(即接收消息超時了)。至因而由於那個節點自己出問題了,仍是網絡不通了,或者是消息出現了嚴重的延遲,是沒法區分的。並且,過一會以後,節點可能會從新恢復(或是本身恢復了,或通過了人工干預)。換句話說,對於出現這種錯誤的節點,咱們只是收不到它的消息了,而不會收到來自它的錯誤消息。相反,只要收到了來自它的消息,那麼消息自己是「忠實」的。
可見,拜占庭錯誤是更強的一類錯誤。在「拜占庭將軍問題」中,叛徒發送先後不一致的做戰建議,屬於拜占庭錯誤;而不發送任何消息,屬於非拜占庭錯誤。因此,解決「拜占庭將軍問題」的算法,既能處理拜占庭錯誤,又能處理非拜占庭錯誤。這聽起來稍微有些奇怪,不過這只是命名帶來的問題。
總之,「拜占庭將軍問題」的解法應該是最強的一類分佈式一致性算法,它理論上可以處理任何錯誤。而Paxos只能處理非拜占庭錯誤。一般把可以處理拜占庭錯誤的這種容錯性稱爲「Byzantine fault tolerance」,簡稱爲BFT。
這樣說來,BFT的算法應該能夠解決任何錯誤下的分佈式一致性問題,也包括Paxos所解決的問題。那爲何不統一使用BFT的算法來解決全部的分佈式一致性問題呢?爲何還須要再費力氣設計Paxos之類的一些算法呢?咱們前面沒有仔細討論解決「拜占庭將軍問題」的算法,因此這裏也不作仔細的分析了。但容易想象的是,提供BFT這麼強的錯誤容忍性,確定須要付出很高的代價。好比須要消息的大量傳遞。而Paxos不須要提供那麼強的容錯性,所以能夠比較高效地運行。另外,具體到Lamport在論文中給出的解決「拜占庭將軍問題」的算法,它還對系統的記時假設(timing assumption)有更強的要求。這也容易理解,既然算法的容錯性要求這麼高,天然對於運行環境的假設(assumption)也有可能要高一點。因爲這個問題是分佈式系統中一個挺關鍵的問題,因此咱們在這裏單獨拿出來討論一下。在Lamport在論文中,算法對於系統的假設有這麼一條:
這條假設要求,若是某位叛徒將軍沒有發送任何消息(固然也多是消息丟失了),那麼這件事是能夠檢測出來的。顯然,這隻能依賴某種超時機制(time-out),依賴節點之間的時鐘達到必定程度的同步,即時鐘的偏移不能超過一個最大值。這其實是一種同步模型(synchronous model)。而Paxos的系統假設在這一點上就沒有這麼強,它是基於異步模型(asynchronous model),對系統時鐘沒有特定的要求。我在以前的另外一篇文章《基於Redis的分佈式鎖到底安全嗎?》一文中也有提到過這個問題。這有時候會成爲分佈式算法帶來一些爭議的根源。
具體來講,根據Paxos的論文所說,Paxos的設計是基於異步(asynchronous)、非拜占庭(non-Byzantine)的系統模型,即:
上面第一條實際上是要求數據在數據庫中持久化,而且要保證在落盤過程當中沒有發生拜占庭錯誤(咱們前面剛提到過)。但實際中因爲忽然斷電、磁盤緩存等現實問題,拜占庭錯誤是有可能發生的(雖然機率很低),因此這就要求工程上作一些特殊處理。
上面第二條,消息損壞,屬於拜占庭錯誤。因此Paxos要求不能有消息損壞發生。這在使用TCP協議進行消息傳輸的狀況下,能夠認爲是可以知足要求的。
綜上分析,解決「拜占庭將軍問題」的算法,提供了最強的容錯性,即BFT,而Paxos只能容忍非拜占庭錯誤。可是,在只有非拜占庭錯誤出現的前提下,Paxos基於異步模型,是比同步模型更弱的系統假設,所以算法更魯棒。固然,Paxos也更高效。
在現實中,真正須要達到BFT容錯性的系統不多,除非是一些容錯性要求很是高的系統,好比波音飛機上的控制系統,或者SpaceX Dragon太空船這類系統(參見www.weusecoins.com/bitcoin-byz…)。
咱們日常能接觸到的BFT的一個典型的例子,就是區塊鏈了。一個區塊鏈網絡是一個徹底開放的網絡,其中的礦工節點(miner)是能夠自由加入和自由退出的。這些節點固然有多是惡意的,因此區塊鏈網絡在設計的時候必需要考慮這個問題。這實際上就是典型的「拜占庭將軍問題」。
接下來爲了將區塊鏈與「拜占庭將軍問題」之間的聯繫討論得更加清楚,咱們先來很是粗略地介紹一下區塊鏈技術。
以比特幣網絡爲例,它的核心操做就是進行比特幣交易,即某個比特幣的擁有者將本身必定數量的比特幣轉移給其餘人。首先,比特幣的擁有者要發起交易(transaction),他須要先用本身的私鑰對交易進行簽名,而後將交易請求發給礦工節點。礦工將收到的全部交易打包到一個區塊(block)當中,並經過一系列複雜度很高的運算找到一個nonce值,保證對於它和區塊內其它信息進行hash計算後的結果可以符合預約的要求。這一步對於整個區塊鏈網絡相當重要,被稱爲工做量證實(Proof of Work)。而後礦工把該區塊在全網發佈,由其它礦工來驗證這個區塊。這個驗證既包括對交易簽名進行驗證(使用比特幣擁有者的公鑰),也包括對工做量證實的有效性進行驗證。若是驗證經過,就把這個區塊掛在當前最長的區塊鏈上。
若是兩個礦工幾乎同時完成了區塊的打包和工做量證實,它們可能都會將區塊進行發佈,這時區塊鏈就會分叉(fork)。但礦工會不停地產生新區塊,並將新區塊掛在當前最長的區塊鏈上,因此最終哪一個分叉變得更長,哪一個分叉就會被多數礦工節點認可。這麼看來,區塊鏈其實不是一個鏈,而是一棵樹。咱們知道,在樹這種數據結構中,從根節點到葉子節點只有惟一的一條路徑。所以,當前有效的區塊鏈實際上是這棵樹中從根節點到葉子節點最長的那條路徑。只要一個區塊在最長的鏈上,那麼它就是有效的,它裏面包含的全部交易就被固化下來了(被多數節點認可)。
咱們只是很是粗略地介紹了一下區塊鏈的工做原理。若是想了解細節,建議研究一下以太坊的官方wiki,地址是:
下面咱們開始討論區塊鏈技術與「拜占庭將軍問題」的關聯。
前面咱們討論「拜占庭將軍問題」的時候,獲得過如下結論:
根據前面的介紹,咱們在區塊鏈中使用的消息應該屬於簽名消息。具體體如今:每個區塊中的交易都進行了簽名,保證沒法被篡改,也能保證這個消息只能是由最初的發起者發出的。那麼,這屬於上述第二種狀況,難道說區塊鏈網絡中忠誠節點的數目沒有要求?顯然不是這樣。好比在比特幣網絡中,要求惡意節點不能掌握多於50%的算力。爲何二者之間彷佛不一致呢?這是由於,「拜占庭將軍問題」只是關注一個子問題,它關注的是其中一個將軍(稱爲主將)向其餘全部將軍(稱爲副官)發送命令的狀況。而最終對全部命令進行彙總則要求全部忠誠的將軍達成共識。若是忠誠的將軍數目太少,無論最終肯定的做戰計劃是什麼,仍是會失敗,由於叛徒可能不執行這個做戰計劃。這相似於比特幣網絡中的狀況,其中對於最長鏈的選擇過程,就至關於將軍們對全部命令進行彙總的操做(按多數投票)。
在「拜占庭將軍問題」中,一個叛徒可能向不一樣的將軍發送不一致的命令。若是算法設計得很差,就可能形成最終沒法達成一致。在區塊鏈網絡中,相似的行爲將會成本很高。這是因爲礦工節點發布區塊的消息必須通過工做量證實,它若是發佈不一致的區塊,每一個區塊都須要工做量證實,這將耗費它大量的算力。另外,這樣作也沒有動機,它只會產生更多分叉,不會產生最長鏈。
在「拜占庭將軍問題」的框架下,如何看待工做量證實呢?它其實至關於提升了作叛徒的成本,從而極大下降了叛徒超過半數的可能性。這裏能夠作一個對比,假設歷史上存在真實的拜占庭將軍問題,那麼能夠想象,敵軍的間諜打入拜占庭將軍這個羣體中的成本應該是很高的。因此,能夠認爲將軍中的叛徒不至於太多。但對應到計算機網絡中,若是沒有相似工做量證實的機制,那麼成爲叛徒礦工的成本就是很是低的。這就頗有可能使得叛徒比忠誠的礦工還要更多。
固然,從經濟學的角度看,在須要工做量證實的前提下,成爲叛徒礦工也是不明智的。由於它既然擁有比較強的算力,還不如按照合理的方式經過挖礦賺取收益更爲穩妥。不過這是技術以外的因素了。
除了工做量證實這種機制(Proof of Work)以外,還有一種被稱爲Proof of Stake的機制。雖然有人質疑這種機制存在缺點(好比nothing at stake),但站在「拜占庭將軍問題」的角度,它也是至關於提升了作叛徒的成本。這就比如一個間諜要混入董事會,成本確定是比較高的,由於他須要首先持有大量股票。
區塊鏈究竟是什麼?有人說是個沒法篡改的超級帳本,也有人說是個去中心化的交易系統,還有人說它是構建數字貨幣的底層工具。可是,從技術的角度來講,它首先是個解決了拜占庭將軍問題的分佈式網絡,在徹底開放的環境中,實現了數據的一致性和安全性。而其它的屬性,都附着於這一技術本質之上。
在今天這篇文章中,咱們從分佈式系統的一致性問題開始談起,直到「拜占庭將軍問題」,最後又跟區塊鏈產生了關聯。這幾部分逐步深刻,雖是「漫談」,邏輯上倒是先後貫穿的。
最後,區塊鏈,是否是一項偉大的革新?是。特別是比特幣系統,它是分佈式系統技術與金融系統業務相結合造就的一次成功的創舉。
區塊鏈技術到底會不會顛覆將來呢?咱們如今只能說:有可能。
(完)
其它精選文章: