區塊鏈技術資源分享
追尋中本聰先生的腳步
?

為什么需要分片Sharding?從全節點的負擔談起_王嘉平

不過,對于現有的單鏈系統,確實有一個不可逾越的物理限制,那就是全節點平均帶寬。

以 13Mbps 的帶寬為例?這是互聯網帶寬中位數,4K 電影在線播放帶寬下限要求為 15Mbps,無論基于什么共識技術,即使完全喪失去中心化,并忽略傳送協議,以及層層封包等額外引入的代價,以比特幣網絡現在的每秒處理 7 筆交易的吞吐量來算,其吞吐量理論上限為6825TPS(7TPS ×? 13Mbps / 8Mb × 600s)。

否則就會出現部分全節點脫網,即長時間無法趕上全網的區塊增長,而離最新頭部塊越來越遠。

我的上一篇已經提到,性能瓶頸和容量瓶頸在現在的結構下無法突破,因為單個全節點的帶寬和存儲資源總是有限的,并且我們還不能要求部署全節點的機器都具備頂級配置,因為只有保證了參與全網的壁壘較低,才能真正具備有良好的去中心化特性。從這個意義上來說,要獲得大幅度的伸縮性,我們必須要能夠有一個合理的設計,使的單個全節點僅僅負責整個網絡吞吐量和容量的一部分,這樣,才有可能在維持全節點的負荷比較小的前提下,使得全網的性能和容量有大幅提升。

分片?Sharding?技術就是針對這一思路提出的。

分片最初是基于數據庫系統提出的,泛指橫向切分數據庫服務器的負荷,用多個數據庫服務器平行服務的方式,以提升整體的服務吞吐量和數據容量。

實際上,分片并不單指一種特定的技術,而是一大類橫向切分系統負荷,多實例并行,以提高整體性能和容量的技術。

不過,分片這個提法在區塊鏈技術中過于寬泛。在這篇文章的最后部分,我會通過引入異步共識組這個概念,談談我認為什么會是區塊鏈中理想的分片方案。

在討論我認為的理想方案之前,我還是用我習慣的邏輯,先向讀者解釋為什么我們需要分片技術、理想的分片技術究竟應該解決什么問題這些最基本的知識;

然后,我會根據自己看過的大量的分片方案,談談目前市面上已有的分片方案存在的五個誤區或謊言。

為什么需要分片:從全節點的負擔談起

在分析具體技術方案之前,先來看看一個全節點都有哪些負荷:

網絡帶寬,這個部分同吞吐量?TPS?線性相關

1. 新區塊的廣播

全節點需要下載周期性出現的新區塊,并進一步上載給其他需要的節點。對于現在 7TPS 的比特幣區塊鏈來說,平均下載帶寬消耗是 13.6Kbps,完全不是負擔。但是如果 TPS 提高到 7000TPS,則至少需要 13.6Mbps 的下載帶寬才能承受——請注意,這個是關鍵數據,并且有序,如果區塊數據得不到及時傳輸,區塊鏈將無法持續構造,并且無法重建全網的賬簿狀態。

2. 未確認新交易的廣播

全節點需要持續發現,并下載尚未被確認的新交易,然后上載給其他節點。在全網不擁堵的情況下,這個數據量和新區塊的數據量相當。相對的,這個數據不需要保序,即使下載不全也不會直接導致全節點本身工作異常。但是,如果這種情況大規模地發生,最終會導致部分交易始終沒有被礦工看到,而長時間不被確認,最終超時。

內存容量,這個部分同用戶量?address 數量?以及智能合約數量線性相關

賬簿的存儲占據主要的內存消耗,其他部分的消耗不多,并且基本不會隨著網絡擴展而增加。

區塊鏈的基本賬簿, 至少需要維護每個用戶?每個 address?上的余額,每個用戶至少需要 16+32 個字節。對于支持智能合約的區塊鏈,每個用戶至少需要額外 32 個字節記錄每個智能合約的代幣的余額。智能合約自身還可以自定義更多的字段,可以占用遠超 32 字節的內容。

當然,并不是所有的用戶都參與了所有的智能合約,所以我們并不以用戶量和智能合約數量的乘積作為內存消耗的估量?,F實的情況是,我們按照以太坊的現狀來估計,約 4500 萬個地址,至少占據了約 3GB 的內存。每個地址平均消耗了 68 個字節。這里并不是說以太坊有了 4500 萬個用戶,通常而言,一個用戶會擁有好多地址。

磁盤 I/O,這個部分同吞吐量?TPS?線性相關

全節點收到區塊并確認成鏈之后,區塊會被寫入磁盤歸檔起來。這個部分的吞吐量大體和下載新區塊的帶寬一致。

這里需要注意的是,按照以太坊的觀點?賬戶模型,賬簿是指全網的某一時刻的全量狀態,而區塊(若干交易的集合)是對賬簿的增量修改信息。在磁盤實際存儲的是區塊,而不是賬簿。節點在啟動的時候,需要重放所有已經記錄的區塊,以構造賬簿的最新狀態。

截至目前,以太坊的全部歸檔區塊數據量已經超過 160GB。這里的一個優化是定期將賬簿全量快照也記錄下來?即 checkpoint,這樣只需要從最近的 checkpoint 開始重放就可以了。

而 UTXO 模型是比特幣的觀點,這是一個非常有意思的結構,它的區塊既是若干交易的集合,同時也是部分賬簿的狀態,即特定地址上的余額。整條鏈上余額不為 0 的 UTXO 都是賬簿的最新狀態。至今比特幣區塊鏈的全部歸檔區塊數據量已經超過 220GB。不過從磁盤 I/O 的角度來看,重建全網賬簿還是需要掃描整條鏈找出全部余額不為 0 的 UTXO,并沒有什么優勢。當然 checkpoint 技術對 UTXO 一樣有效。

在這個領域,最近我看到了一些被熱炒的改進,尤其是在已確認交易集合的聚合表示方面。我注意到斯坦福大學的一個團隊最近提出,RSA累加器(RSA Accumulator)可以代替Merkle Tree,用來表示一個已確認交易的集合。

這個想法的優異之處在于,可以直接用一個交易的Hash值來校驗一個交易是否存在于已確認交易的集合,而Merkle Tree不僅需要一個交易的Hash,還需要從樹根到該交易沿途路徑上的所有兄弟節點上的Hash。不過,這個做法的代價是,這個表示本身要1.5K字節,Merkle Tree的根僅需要20或32個字節。同時,這并不意味著全節點可以不再保存歷史交易,原因在于,首先集合的聚合表示是不具備枚舉的能力的,也就是說,在交易未知的情況下,集合的聚合表示無法告訴你里面具體的交易是什么,所以你也無法判讀這個集合本身是不是正確的,所以全節點也無法僅憑這個信息確認鏈頭的正確性。

全節點在自舉的時候還是需要從創始區塊(genesis block)開始下載,逐塊驗證全鏈的完整性和正確性。但是,當這個驗證過程完成之后,為了節省空間全節點,是可以刪除掉區塊中的實際交易內容的,其代價是喪失枚舉交易的能力,同時也喪失了幫助其他全節點自舉的能力。

另外,通過驗證一個交易是否在鏈頭上,來確定賬戶余額的做法,僅對于UTXO交易模型有效。對于以太網這樣每個交易僅為增量修改信息的交易模型,僅靠驗證一個交易是否在鏈頭上,是無法得知賬戶的余額的。

CPU 處理能力,這個部分同吞吐量?TPS?線性相關

1. 密碼學相關計算

對于每一個收到的新區塊,無論最終時候成功成為鏈的一部分,全節點都需要驗證其攜帶的每一個交易是否被正確簽名。同時會驗算每個區塊的 Hash,以確保其達到了當前工作量證明PoW?難度的要求。對于拜占庭容錯?BFT?算法,還需要驗證各個委員會成員的簽名是否正確。

這里主要的工作量是驗證簽名。驗證簽名在一臺普通計算機上[email protected], C++ 并行實現?的速度可達 40K op/s,也就是 4 萬 TPS?每個交易需要驗簽一次。

2. 交易驗證相關計算

對于每個交易,如果是支付交易,將需要至少查找一次賬戶的索引結構?通常為哈希表,并做一次加法和大于的判斷;為了更新賬簿,還需要至少一次加法和減法。這樣的一系列操作,在一臺普通計算機上的速度可以輕松達到 1M op/s。如果是智能合約,會需要在虛擬機中執行對應的智能合約指令,對于現有的金融本質的應用?包括類似 Cryptokittes 類或 Fomo3D 類的區塊鏈游戲,至少可以達到 100K op/s。

這意味著什么?

針對上面的分析,我來做一個小結:對于一臺普通的計算機,擁有 13Mbps 的互聯網連接,[email protected] 4Core 的 CPU,16G 內存,512G SSD 硬盤?250MB/s。網絡帶寬導致的 TPS 理論上限約為 7 千 TPS,硬盤文件 I/O 導致的 TPS 理論上限為 5 萬 TPS,CPU 處理能力導致的的 TPS 理論上限約為 5 萬 TPS。另外,內存大小導致的地址理論上限約為 2.5 億個地址。

這里可以看到,對于性能來說,網絡帶寬是最首要的瓶頸根源,其次是硬盤的I/O和CPU的處理能力。對于容量來說,內存是最主要的瓶頸根源。

下一篇:《分片應該做到什么?分片方案的一些誤區


歡迎大家通過我的微信公眾號「王嘉平」和知乎專欄「去中心化數字世界隨想」,就這個話題展開更多討論。

為什么需要分片Sharding?從全節點的負擔談起_王嘉平

分享到:更多 ()
0
區塊鏈神吐槽
pi幣注冊流程教程圖解中文版

來評論吐槽 搶沙發

評論前必須登錄!

 

區塊鏈資源分享聯系我

區塊鏈資源分享聯系我首頁更多新聞
做滴滴代驾还是开滴滴那个赚钱