區塊鏈共識機制分析——論PoW,PoS,DPos和DAG的優缺點
近期,隨著區塊鏈技術在社群中的聲音越來越大,業界已經開始從技術角度對區塊鏈進行全方位的解讀。作為第一批區塊鏈技術的實現,傳統比特幣與以太坊在共識機制、儲存機制、智慧合約機制、跨鏈通訊機制等領域並沒有非常嚴密的設計,從而引發了一些在資料庫與儲存領域比較常見的問題,導致其資料規模無法無限增加(當前僅幾百GB就產生了嚴重的效能瓶頸,幾乎不可能到達上百TB規模),吞吐量極為有限,使其不可能適應通用分散式資料儲存或通用結算體系的要求。
作為資料庫核心行業十幾年的老兵,筆者將會從共識、儲存、智慧合約、多鏈、快速檢索、以及通用介面等幾個維度對區塊鏈技術進行闡述,並會與資料庫及大資料分散式計算技術進行橫向對比。
區塊鏈的本質即分散式多活資料庫。
從產品功能的角度看,當前的區塊鏈產品與資料庫相比存在極大的差距。尤其是對於在業界存在了幾十年的關係型資料庫,其主要核心功能包括增刪改查,而主要結構則包括SQL解析、日誌、資料管理、以及索引管理幾大模組。
而大資料技術興起後,業界開始使用PC伺服器替代傳統小型機,為了避免伺服器掉電導致的資料頁損壞,分散式資料庫或儲存普遍使用三副本對資料進行冗餘儲存。
儘管從功能上看,當前區塊鏈技術僅僅是資料庫的一個微小子集,但是其一系列設計機制,與傳統資料庫的核心理念極為相似。譬如,從其傳輸和儲存的資料結構上來看,區塊鏈的鏈式結構來源於傳統資料庫的事務日誌。任何資料庫的DBA都知道,資料庫的事務日誌本質上就是不可更改的鏈式結構,事務中的每一條操作記錄都會有一個反向指標指向該事務中的上一條記錄。因此,區塊鏈的鏈式結構本質上脫胎於資料庫事務日誌,同時增加了區塊之間的反向雜湊值作為指標,且引入了默克爾樹結構進行快速資料校驗。因而,我們可以安全地進行認為:區塊鏈的鏈式結構在儲存體系中等價於資料庫的事務日誌。本質上資料庫的任何操作同樣是不可篡改的,只不過當前大部分資料庫不會對外暴露事務日誌的解析工具,僅儲存每一條記錄的最終狀態而已。
(圖1:資料庫體系結構,黃色部分代表區塊鏈同樣包含的組建)
1.1 一致性原理對比
在分散式資料庫中,當前普遍採用PAXOS或RAFT演算法進行資料多份冗餘的一致性協商。一般來說,在分散式資料庫體系中,每個資料分片由至少3個互相冗餘備份的節點構成,而在正常執行時的資料庫每個分片都會存在一個主節點與兩個從節點。其中主節點負責資料的讀寫操作,從節點進行只讀操作。當主節點寫入資料時,其事務日誌會被實時同步給其他從節點進行回放,以達到主從節點之間資料一致性的目標。
(圖2:資料庫主從節點同步)
那麼對比區塊鏈的體系,可以認為資料庫領域的主節點即日誌生成節點,其每次生成事務日誌的功能,與區塊鏈中每次出塊時礦工的功能完全等價。唯一不同的是,資料庫在每次操作時對日誌實時廣播到從節點中,並且在事務提交時進行一致性判斷。而區塊鏈則採用檢查點方式,每個節點接收自己的交易請求,並將請求廣播到其他節點中,而每一次出塊操作即產生一個檢查點,該檢查點包含的資訊即出塊節點向區塊中寫入的所有記錄。這些記錄被髮送到其他節點後,每個節點對資料塊中的記錄進行驗證並永久寫入自身的交易日誌(即區塊檔案)。
(圖3:區塊鏈節點互相對等)
但是,區塊鏈和資料庫在一致性選擇上最大的不同在於哪個節點成為檢查點發起的節點。資料庫由於採用了主從機制,主節點永遠是日誌的發起節點,而從節點永遠是日誌回放與驗證節點。但是區塊鏈則不同,其採用某些演算法(例如PoW、PoS、DPoS等)在多個參與節點之間定期選取一個節點進行檢查點確認,這也是區塊鏈號稱自身安全的一個理由所在:在全網大量的節點中攻擊者無法確定下一個檢查點確認的節點是誰(當然,就算攻擊者確定了下一個出塊節點,還有一系列的數字簽名機制保障事務不被偽造和篡改)。
因此我們可以安全地認為,從檢查點節點選擇的領域來看,傳統分散式資料庫確定主節點生成事務日誌的機制,是區塊鏈共識機制的一種簡單實現。也就是說,如果區塊鏈共識機制每次都選取同一個節點作為出塊節點,其機制基本等價於分散式資料庫的主從複製原理(資料庫按照事務提交進行一致性驗證,區塊鏈不存在事務的概念,因此按照資料塊進行一致性驗證)。
(圖4:資料庫以提交回滾操作作為檢查點,區塊鏈以生成區塊作為檢查點)
1.2 共識演算法
由於區塊鏈體系中並不存在某個節點永久作為檢查點確認的節點,而是每個參與節點都有機會被選舉成為該角色,因此在每個節點都能夠進行讀寫操作時,整個區塊鏈體系從功能上等價於一個不支援事務機制的多活資料庫。而具體使用哪種演算法選擇出塊節點(PoW與PoS之爭)、哪些節點在接收到資料塊時該如何驗證(PoS與DPoS之爭)、節點之間的資料以什麼方式進行傳播(DAG與鏈式結構之爭)、以及如何確保一條交易被大多數參與節點所接受(PBFT、Paxos、RAFT、以及各種分叉解決方案等演算法之爭,Hyperledger 1.0甚至直接使用中央Kafka做排序也是醉了),則是區塊鏈共識演算法需要回答的問題。不同的解決方式制約著區塊鏈的一致性、效能、吞吐量、以及可靠性。
1.2.1 挖礦
挖礦是來自於比特幣的一種說法,其本質在於多個節點通過PoW演算法選舉出一致性檢查節點。關於PoW的說明業界已有無數文章分析,這裡筆者不再贅述細節。實際上,從資料管理的角度來看,PoW是一種效率極為低下的暴力機制,通過不停地迴圈生成隨機數並進行雜湊,通過網路預先廣播的規則(複雜度),讓每個參與的節點自證明其是否符合成為檢查點的資格。
對比分散式資料庫的Paxos或RAFT演算法,每個參與節點預設自身有資格成為主節點,在原本的主節點無法連通的情況下通過最新事務號或其他原則相互投票,從而選舉出新的主節點。而由於競爭節點過多,區塊鏈作為一個擁有幾萬甚至幾十萬複製節點的多活資料庫,繼續採用Raft或Paxos演算法一方面複雜度太高,另一方面無法解決拜占庭問題,因此比特幣採用PoW機制,通過大家公認的某種機制,讓每個參與節點首先自己判斷是否符合要求(即生成了隨機數後自己進行雜湊並驗證)。當節點自身認為符合條件後,將之前生成的隨機數以及打包好的日誌(資料塊)廣播給叢集中其他節點,從而大幅度減少了節點間相互投票所需的複雜度。
節點通過迴圈生成隨機數並自我驗證的過程,即PoW中所謂的“挖礦”階段。
因此,如果把挖礦的概念擴充套件,不論是PoS、PoW或DPoS演算法中,節點間競爭成為檢查點的過程即挖礦過程。
1.2.2 PoW與PoS的選擇
PoW是一種極為粗暴原始,但卻又及其有效防止惡意攻擊的選舉演算法。該演算法與計算機核心中多執行緒協作的自旋鎖有異曲同工之處,自旋鎖的原理在於通過執行緒自身不停迴圈判斷一個記憶體地址狀態,直到該狀態設定為空閒後,通過CPU原子操作將其置為鎖定狀態,以此和其他執行緒進行互斥的機制。這種機制和PoW極為相似。
而PoS更傾向於類似Raft投票機制,通過固定時間協調所有節點參與投票,根據某種規則(例如持有代幣數量、或提供儲存空間大小等)判斷每個節點的權重,最後選取權重最高的節點作為檢查點節點。而在資料庫一致性選擇的Raft演算法中,普遍會根據最新事務號作為權重,多個節點之間優先選擇包含最新事務記錄的節點作為主節點。
因此,可以看到PoW與PoS最大的區別在於,PoW在演算法複雜度足夠高的前提下,基本不需要太多的節點間互相通訊和確認,對程式碼的實現要求極低。而PoS對於多節點間一致性驗證、防偽等要求較高,但是很大程度上可以沿用傳統一致性選舉的思路進行一定程度的優化即可。
(圖5:PoW與PoS流程對比)
但是PoW的缺點與自旋鎖一樣,對於計算資源的要求極高。一個被錯誤應用的自旋鎖可以輕易消耗掉計算機中所有的CPU資源,同樣PoW當前被人們詬病的最大問題也在於資源消耗。PoS在這方面則沒有任何問題。
1.2.3 PoS與DPoS的選擇
類似Paxos與Raft,叢集內參與的節點越多則效率越慢。一個典型的分散式資料庫,使用單副本的效率可能會是三副本的兩倍,而三副本的效率則又是七副本的兩至三倍。因此,為了滿足足夠的吞吐量,使用PoS在進行選舉時務必不能在成千上萬個節點之間進行投票選舉,而是應當在有限的集合範圍內進行投票驗證。這就是DPoS的核心原理。
DPoS給出一種思路,將成千上萬個PoS節點,通過某種機制(例如持有代幣的數量)選舉出若干(奇數個)節點,在這幾個節點之間進行投票選舉(在一些實現中甚至會在這些節點間以令牌環的方式進行輪詢,進一步減少投票開銷)出每次的檢查點(出塊)節點,而不用在網路中全部節點之間進行選擇。
這種機制能夠大幅度提升選舉效率。在幾十個最多上百節點之間進行一致性投票一般來說可以在秒級完成並達到共識,因此DPoS機制可以將檢查點(事務確認時間)提升到秒級,通過減少投票節點的數量或採用令牌環機制甚至可以降低到毫秒級。
(圖6:PoS對比DPoS)
但是,DPoS的效能無法無限提升。在一個完美的軟體實現中,其效能與吞吐量則物理制約於節點間通訊的網路頻寬。一般來說,對於公網環境中兩個節點之間的頻寬能夠維持在上下行均5MB/s(50兆頻寬)則相當優秀了,大部分情況下遠遠無法達到該數值。而如果每條交易日誌需要100位元組,由於網路即需要廣播交易也需要廣播日誌,則網路頻寬消耗加倍,因此在兩個節點的單鏈中最大吞吐量不超過2.5萬每秒(5MB/100位元組/2=25000),假設叢集中包含更多節點,則最大吞吐量需要根據其使用的P2P同步機制成比例縮減。如果需要進一步提升則需要進行分鏈(類似於資料庫分片的概念),該主題將會在下面的章節詳細討論。
1.2.4 DAG與鏈式結構的選擇
DAG與鏈式結構的本質區別在於非同步與同步通訊。在前文中已經討論過鏈式結構的本質等同於資料庫事務日誌,而出塊操作則為檢查點操作,那麼鏈式結構體系可以看做是定期同步檢查點的資料庫事務同步機制。
而DAG則通過將事務操作進行非同步處理來增加網路吞吐量,採用謠言傳播演算法在節點間傳送操作日誌,並通過某種機制(IOTA每次驗證前兩條交易,並計算一個PoW代表權重)將一個權重賦給該操作。
相比起同步操作的鏈式結構,DAG結構與任何非同步機制一樣,能夠帶來的提升在於吞吐量(真的麼?後文會有描述),但是可能產生的問題則在於無法有效預測交易被確認的時間與週期,並且操作之間的順序無法最終在多個節點間確認保持一致。
由於當前市面上DAG的實現相對較新,暫時還存在一些理論上未突破的侷限性,包括:
- 在對歷史交易驗證時採用隨機方式,而沒有任何先後規則,那麼有可能產生某些交易在極端情況下沒有任何其他節點對其驗證,從而永遠不會被確認。這個問題在IOTA中通過多次重試的方式解決,但是是否存在更好的一次性確認機制能更有效地解決該問題值得探討;
- 為了追蹤每一筆交易與之前交易的關係,整個DAG圖譜需要被隨時檢索和訪問。在一個較大規模的系統中其交易圖譜溯源會非常複雜,同時幾乎不可能被全部儲存在記憶體中以進行實時更新。而如果將這些資料儲存在磁碟上,那麼實時重新整理每個Tangle的權重會造成大量隨機I/O(也許可以通過大量部署SSD解決),因此從工程實現上來看優化難度較大;
- 由於DAG的操作記錄寫入順序不存在“區塊”或“日誌”這類檢查點機制,因此每個節點各自為政,對於全域性順序無法得到保障。在這種情況下,在非等階操作時可能存在不一致的問題(例如對同一條記錄,在兩個不同的節點同時執行轉賬(加減法)和計息(乘法)操作,兩個節點得到的操作順序有區別,導致賬戶餘額最終結果不一致)。
如今從DAG衍生出一些其他資料結構(例如雜湊樹等),基本上只是從儲存方式上有一些特定的優化,但是整體上與DAG所帶來的問題保持一致。
筆者認為,DAG的非同步資料分發思路完全可以與鏈式結構相輔相成。在最終理論完善之前其應用場景應當被謹慎選擇,避免過早將其直接應用於通用化正規化的場景。
1.3 結論
在區塊鏈的共識機制中,其本質與分散式資料庫的一致性演算法存在極多的相似之處。拜占庭問題的引入僅僅從演算法和選舉節點數量上對網路結構做出一些調整,但是並不從本質上改變分散式系統一致性選舉的機制。
(圖7:區塊鏈共識機制對比)
PoW採用簡單粗暴但極為有效的方式,通過節點首先自證其資質後才進行廣播的方式,大幅度減少了網路間的通訊壓力,但與之帶來的問題則在於自證資質的計算資源消耗極大。
PoS採用與傳統分散式一致性驗證類似的機制,通過代幣數量(或儲存容量等指標)作為權重依據,使用某種分散式演算法選舉出每次的檢查點節點。這種機制的好處在於沒有消耗計算資源的自證資質過程,但是帶來的問題在於每次選舉時在大量節點的網路中對網路壓力極大。
DPoS作為PoS的變形,通過縮小選舉節點的數量以減少網路壓力,是一種典型的分治策略:將所有節點分為領導者與跟隨者,只有領導者之間達成共識後才會通知跟隨者。該機制能夠在不增加計算資源的前提下有效減少網路壓力,在優秀的軟體實現中將會具有較強的應用價值。
DAG則採用非同步機制替代鏈式檢查點的同步策略,但是由於其核心不存在一個標準的一致性確認機制(即賬本或日誌體系),同時無法對操作順序進行全域性統一排序,因此短期看來理論基礎還有待突破。但是,從長期看來,DAG是一種非常新穎且有前景的機制,為傳統資料管理領域的思維打開了新的大門。
文章出處:http://www.8btc.com/blockchain-concensus-mech