摘要:本文聚焦Fabric核心業務,構建一個測試模型,對社區原生的Fabric和華為雲區塊鏈(基於Fabric)進行實測,識別社區原生Fabric的性能瓶頸,並嘗試通過華為區塊鏈提供的動態伸縮、快速PBFT算法進行調優,提升幾個關鍵的評測指標。
1、Fabric 性能測試現狀
通俗的來講,區塊鏈是一種按照時間順序將數據區塊以順序相連的方式組合成的一種鏈式數據結構,並以密碼學方式保證的不可篡改和不可偽造的分布式賬本。比特幣(Bitcoin)、以太坊(Ethereum)、超級賬本(Hyperledger)都是典型的區塊鏈系統。其中Hyperledger Fabric是最受歡迎的企業級區塊鏈框架,Fabric采用了松耦合的設計,將共識機制、身份驗證等組件模塊化,使之在應用過程中可以方便地根據應用場景來選擇相應的模塊。
Fabric的性能是用戶最為關注的問題之一,然而,目前沒有一個權威中立的機構,根據公認的規則,對Fabric進行性能測試並給出測試報告,大概有下面幾個原因:
(1)Fabric還處在快速發展中,尚未給出詳細中立並且公認的測試規則;
(2)Fabric網絡結構(網絡帶寬、磁盤IO、計算資源等),配置參數(如區塊大小、背書策略、通道數量、狀態數據庫等),共識算法(solo,kafka,pbft等)都會影響評測結果,很難構建反映fabric 全貌的測試模型;
(3)Fabric 交易過程復雜,和傳統的數據庫有很多區別,也不適用於傳統的測試方案和工具;
本文聚焦Fabric核心業務,構建一個測試模型,對社區原生的Fabric和華為雲區塊鏈(基於Fabric)進行實測,識別社區原生Fabric的性能瓶頸,並嘗試通過華為區塊鏈提供的動態伸縮、快速PBFT算法進行調優,提升幾個關鍵的評測指標。
2、Fabric 交易過程分析
在Fabric交易過程中,涉及不同的角色,每個角色承擔不同的功能,節點(Peer)可細分為背書節點(Endorser peer)和提交節點(Committer peer),共識由排序(Orderer)角色完成。交易流程如下:
圖1:fabric交易流程簡圖
(1):應用程序客戶端通過SDK向區塊鏈網絡發起一個交易提案(Proposal),交易提案把帶有本次交易要調用的合約標識、合約方法和參數信息以及客戶端簽名等信息發送給背書節點(Endorser)。
(2):背書節點(Endorser)收到交易提案(Proposal)后,驗證簽名並確定提交者是否有權執行操作,驗證通過后執行智能合約,並將結果進行簽名后發還給應用程序客戶端。
(3):應用程序客戶端收到背書節點(Endorser)返回的信息后,判斷提案結果是否一致,以及是否參照指定的背書策略執行,如果沒有足夠的背書,則中止處理;否則,應用程序客戶端把數據打包到一起組成一個交易並簽名,發送給Orderers。
(4):Orderers對接收到的交易進行共識排序,然后按照區塊生成策略,將一批交易打包到一起,生成新的區塊,發送給提交節點(Committer);
(5):提交節點(Committer)收到區塊后,會對區塊中的每筆交易進行校驗,檢查交易依賴的輸入輸出是否符合當前區塊鏈的狀態,完成后將區塊追加到本地的區塊鏈,並修改世界狀態。
客戶端通過Fabric完成交易,要感知三個步驟(收集背書,提交排序和確認結果),而傳統的數據庫的讀寫,只要發起請求,等待確認即可。如果使用經典的測試工具如JMeter,需要將fabric sdk進行包裝RESTFul接口,增加了評測的復雜度。幸運的是,2017年5月超級賬本社區推出Caliper,允許用戶通過一系列預置的用例來測試特定的區塊鏈技術實現。Caliper生成的報告將會包含一系列區塊鏈性能指標,如TPS(平均每秒交易數),時延,系統資源占用等。本文的評測結果均為Caliper工具來測試生成。
3、Fabric 測試模型構建
建立性能測試模型,主要包含兩部分工作:一是根據業務特點提取評測指標;二是確立穩定可測的業務模型。
3.1 評測指標
Fabric是一個典型的分布式系統,Fabric網絡中各個Peer獨立部署,分別維護自己的賬本(支持背書查詢),內部通過Gossip通信完成狀態的同步。Fabric符合分區容忍性,根據分布式系統的CAP定理,Fabric在保證可用性的前提下,無法確保一致性。Fabric是通過最終一致性(弱一致性的一種)來保證所有的節點最終就世界狀態達成一致,這個過程就是Orderer共識和Peer驗證確認的過程。因而在我們的測試模型中,主要考察以下指標:
查詢吞吐量(Query Throughput):每秒處理的查詢請求量
共識吞吐量(Consensus Throughput):每秒處理的共識請求量
一致性吞吐率(Consistency Throughput):每秒完成的同步業務數
平均時延(Avg Latency):完成一次事務的平均耗時
失敗率(Fail Rate):出現業務失敗(含超時)的比例
3.2 業務模型
在業務場景的選擇上,我們盡可能考慮主流場景,擯棄本身就是瓶頸的選項,聚焦區塊鏈的核心業務。
基礎設施方面,Orderer和Peer節點我們選擇主流的8vCPU16G規格的虛機,Client選擇一台32vCPU64G的虛機。整個測試在一個穩定的子網內完成。Orderer節點我們配置4個,滿足3f+1容錯的最低要求。Peer節點我們配置1,根據需要最多擴容到5個。
配置參數方面,我們使用單通道,單組織背書,狀態數據庫選擇goleveldb。落塊策略使用默認策略(2s/4M/500T)。
共識算法方面,可選擇solo、pbft、kafka。solo模式為測試模式,無法用於生產環節。Kafka模式一種支持CFT容錯的共識算法,性能主要依賴外掛的kafka集群性能。而pbft能夠防范拜占庭節點,應用場景更廣泛,對性能的要求也更高。因而,本次測試選擇pbft作為共識算法。
鏈代碼方面,我們選擇社區提供的chaincode_example02示例,業務數據占比很低,同時能夠覆蓋賬本讀寫的基本用例。
4 、實測與調優
4.1 查詢性能與動態伸縮
Fabric 查詢性能其實就是就是一次背書請求。Peer端主要包含3個過程。
(1)校驗Proposal簽名;
(2)檢查是否滿足Channel ACL;
(3)模擬執行交易並對結果簽名;
代碼可以參考社區chaincode_example02。
Test | Name | Succ | Fail | Send Rate |
Avg Latency |
Query Throughput |
1 | query | 10000 | 0 | 962.6tps | 0.01s | 962tps |
2 | query | 25000 | 0 | 2493.5tps | 0.07s | 2492tps |
3 | query | 50000 | 0 | 4992.0tps | 6.68s | 2503tps |
圖2:單組織單Peer的查詢性能
可以看到,單節點(8vCPU,16G)的讀性能在2500tps左右。觀察監控指標發現,CPU使用率在70%左右,接近滿載,而內存使用率只有25%左右[z(3] 。這個不難理解,背書過程涉及大量的驗證、簽名工作,這些都是計算密集型操作。根據區塊鏈符合CAP定理的分區容忍性,我們可以水平擴展組織內Peer來提升性能。華為區塊鏈已經提供了這個伸縮特性,我們將peer的個數擴容為5個。
圖3:華為BCS的動態伸縮特性
再次運行測試腳本,結果如下:
Test | Name | Succ | Fail | Send Rate |
Avg Latency | Query Throughput |
1 | query | 10000 | 0 | 971.4tps | 0.01s | 971tps |
2 | query | 25000 | 0 | 2495.8tps | 0.01s | 2494tps |
3 | query | 50000 | 0 | 4977.1tps | 0.01s | 4974tps |
4 | query | 12000 | 0 | 11898.9tps | 0.06s | 11869tps |
圖4:華為BCS單組織5Peer的查詢性能
可以看到,在不斷服,不犧牲穩定性的前提下,通過將單Peer動態伸為5Peer。性能可以提升4倍多,整體吞吐量超過10000tps,平均延時只有0.06s。
4.2 共識性能與共識算法
共識算法是提升共識性能的關鍵。社區fabric v1.0.0-alpha2版的提供了PBFT共識是一種實用拜占庭算法。實用拜占庭算法主要改進了拜占庭算法效率不高的問題,將算法復雜度由指數級降低到多項式級,使得拜占庭容錯算法在實際系統應用中變得可行。
我們先用社區的PBFT共識測試下:
Test | Name | Succ | Fail | Send Rate | Avg Latency |
Consensus Throughput |
Consistency Throughput |
1 | invoke | 1000 | 0 | 959.5tps | 5.53s | 574tps | 518tps |
2 | invoke | 2000 | 0 | 1996.4tps | 14.84s | 567tps | 520tps |
3 | invoke | 5000 | 0 | 4889.8tps | 37.90s | 579tps | 503tps |
圖5:社區原生PBFT的共識性能
可以看到,社區原生的PBFT共識,無論是吞吐量,還是平均延時,都比較差。華為PBFT算法具備Early-Stopping性質,即當不存在拜占庭節點時,整個網絡將很快達成共識,因而速度應該很快。我們切換為華為快速PBFT共識算法,再實測一下:
Test | Name | Succ | Fail | Send Rate | Avg Latency |
Consensus Throughput |
Consistency Throughput |
1 | invoke | 10000 | 0 | 973.6tps | 1.32s | 970tps | 917tps |
2 | invoke | 20000 | 0 | 1976.5tps | 1.24s | 1971tps | 1789tps |
3 | invoke | 50000 | 0 | 4995.4tps | 4.21s | 4985tps | 1677tps |
4 | invoke | 100000 | 0 | 11133.2tps | 9.91s | 11031tps | 1502tps |
圖6:華為BCS 快速PBFT的共識性能
切換到華為PBFT算法后,共識吞吐率可以達到10000tps,一致性吞吐量也接近1800tps。同時,相對社區原生版本,平均時延也大幅縮短。這樣的寫性能和傳統的單節點關系數據庫相當,可以滿足大部分商用場景。
4.3 關於最終一致性
在共識性能的測試過程中,我們發現當共識吞吐量超過2000時,Peer在同步區塊時會出現積壓,導致平均時延增大。要詳細了解原因,可以通過查閱Fabric的關鍵源代碼 (gossip/state/state.go)來了解Peer落塊的過程:
圖7:gossip 同步區塊流程圖
在fabric中,賬本數據主要由GossipStateProvider通過Gossip協議來同步,這里只能給出關鍵的流程。
(1)啟動一個協程deliverPayloads從orderer或其它Peer獲取 “毛坯塊”,調用LegerResources.StoreBlock;
(2) LegerResources調用Validator校驗交易是否符合背書策略,檢查讀集合中版本跟賬本是否一致;
(3)LedgerCommittor執行區塊中的合法交易,更新賬本狀態;
(4)ServiceMediator更新通道元數據;
筆者修改了一下源代碼,增加了4個步驟的耗時統計,結果顯示40000交易生成200塊的情況下,步驟2(校驗)耗時17s,和步驟3(寫塊,更新索引)耗時40s。二者占用deliverPayloads 80%的耗時,猜測是一致性吞吐率的瓶頸。開啟Profile模式后,監控堆棧調用情況,也進一步驗證了這個猜想。[z4]
圖8:gossip 同步區塊Profile火焰圖
筆者能想到的優化方案:
(1)使用高速讀寫盤(SSD),提高區塊文件的讀寫效率;
(2)Validator校驗環節是計算密集型,是否可以借助軟硬件結合的方法,大幅提升校驗效能;
(3)目前Gossip拿到Payload數據后,只能串行逐一處理。是否可以根據區塊的讀寫集進行分區,交給不同的線程處理,最后再歸並落盤,來提升性能(參考多通道性能是單通道的倍級);
筆者通過媒體了解到,華為區塊鏈等產品團隊,已經在這方面投人力進行預研,期待可商用的產品早日發布,回報社區。
5、總結
Fabric作為最受歡迎的企業級區塊鏈解決方案,已經在很多領域得到成功應用。在本次測試調優中,發現社區原生Fabric有很多局限,如不易擴展,性能較差,不建議直接用於生產環境。
華為區塊鏈的伸縮特性和快速PBFT算法,能夠快速提升Fabric交易性能。其中伸縮特性,可以在不斷服的情況下,將查詢性能提升到10000tps以上(單peer的4倍多)。而快速PBFT算法,可以將共識吞吐率可提高到10000tps以上(社區原生的20倍),能夠滿足大部分商用場景。
同時發現,在高並發的情況下,最終一致性的平均時延會出現增長,主要原因為當前區塊校驗和落盤為順序串行執行,無法充分利用多核資源。如果社區后繼版本或商業公司,能通過軟硬件結合,分區歸並的思路,提升一致性吞吐率,降低時延,Fabric將會在商用領域獲得更大的成功。
6、參考資料
https://hyperledger-fabric.readthedocs.io
https://github.com/hyperledger/caliper
https://github.com/hyperledger/fabric
https://github.com/yeasy/hyperledger_code_fabric
Performance Benchmarking and Optimizing Hyperledger Fabric.pdf