“我的區塊鏈能跑多少TPS?”“能不能達到‘官方’所說的峰值?”“為啥總是壓不上去?是我的機器不夠好嗎?”
如今,區塊鏈技術被廣泛應用在各行各業中,也接受海量使用者、海量資料的挑戰,越來越多同學開始關注鏈與合約的效能。
本文分別從原理、實操和技巧三個方面,為大家提供了詳盡的FISCO BCOS效能壓測指引,結合例項進行演示,總結出壓測實用技巧與常見問題,以便大家更好地提升效能。
壓測原理
壓測這事,原理其實不復雜,起一個或一堆區塊鏈客戶端,先往鏈上部署一個用來壓測的合約或者需要評估效能的智慧合約,然後卯足了勁往鏈上“併發”傳送交易,收到區塊鏈返回的交易執行結果(交易回執)後,統計出TPS。
由於區塊鏈分散式網路廣播、交易排隊打包、共識確認等流程還是比較漫長的,中間充滿了技術細節,往往導致結果不如預期,這就需要在環境、引數、壓測程式以及合約邏輯等方面下功夫,才能得到理想的結果(把計算資源用到極致)、以及確切的結果(我的環境峰值就這麼高了)。
深入壓測細節
壓測前先“調參”
壓測這事一般來說是一個長時間的“力氣活”,在啟動之前,一定要先做好足夠的準備。以下一些關鍵引數,要先調到“最優”。
總交易數:壓測程式在一次壓測中總共傳送的交易數量。強調一下,如果沒有達到一定數量級的交易,壓測結果沒有統計含義。比如實際TPS應該可以達到5000,那麼只發幾千到一兩萬交易的話,因為程式啟動和停止等邊界條件影響,結果意義不大,至少超過兩個數量級的交易數(比如10萬筆、整個過程持續1分鐘以上),才能看出平穩處理階段的TPS表現。
QPS(Queries Per Second):每秒請求數,即壓測客戶端傳送交易的速率。形象地說就是:壓測客戶端能不能“餵飽”鏈節點,比如鏈的TPS效能在萬級,那麼一個壓測客戶端的傳送能力是否足夠,要具體評估,一個不夠,就要起多個壓測客戶端,而且每個客戶端傳送的模式應該是非同步的,如果每次都是傳送一個交易然後同步等結果再發下一個,是很難“餵飽”區塊鏈節點的(如何確保非同步,參見SDK的介面定義)。
但是,QPS也不能過大,當QPS過大時,會讓交易堆積在交易池中。這些堆積的交易不能被立即執行,使得測出的TPS會小於實際的TPS。
合約複雜度:合約的複雜度對TPS結果會有極大影響。合約複雜度簡單的理解就是程式碼量(對應指令數)、資料量(具體來說就是合約裡牽涉的狀態資料量),還有很重要的一點是合約是否支援並行事務邏輯。並行才能用盡伺服器資源,要達到並行處理效果,除了上一條所說的壓測客戶端需要非同步傳送之外,FISCO BCOS的合約是支援DAG平行計算的,一個普通合約,如果在事務上可以支援並行,開啟DAG並行設定,才能用盡伺服器上所有的CPU計算能力,否則實際上也是在“序列”處理,只用了一個CPU,效果肯定不會太好。
DAG並行合約開發參見:
https://fisco-bcos-documentat...)
鏈引數配置: 有幾個關鍵的鏈引數和效能表現相關,包括多長時間出一個區塊,一個區塊裡能打包多少個交易。在壓測場景裡,這幾個數字要配置得比較合適,我們預設500ms嘗試將交易池(大小:[tx_pool].limit)中的交易打包成一個區塊(打包間隔:[consensus]. min_block_generation_time),每個預設最多1000筆交易(區塊最大交易數:tx_count_limit)。
同時,節點會自動保證在1秒內出一個塊。如果出當前區塊的時間大於1秒,下一個區塊會少打包一些交易,若小於1秒,會根據設定的區塊最大交易數上限盡量打包交易。若單純為了壓測,推薦將打包間隔儘可能調小,並反覆調節區塊最大交易數,讓出塊時間均勻穩定的同時,儘量逼近最大值。此處推薦將打包間隔設定為1ms,區塊最大交易數最低為10000筆起步,根據實際結果向上調整。可參考文末“FISCO BCOS 配置文件”進行配置。
硬體配置:如果想要得到儘量高的TPS,要採用效能更好的硬體。具體而言就是伺服器核數越多越好,記憶體越寬裕越好;一定要用高速機械硬碟或SSD硬碟,慎用相對低速的網路儲存裝置,硬碟的IO速度對鏈的區塊和狀態寫入速度有巨大的影響;網路頻寬越大延遲越低越好,保證壓測程式和鏈節點之間的網路,以及節點和節點之間的網路是暢通高效的。
其他調整:壓測客戶端和鏈的日誌級別最好開到Error級,儘量地減少日誌輸出量。環境裡如有其他佔用資源(CPU、記憶體、硬碟網路等)的程式,不妨暫時退出。之前有開發者的壓測把硬碟寫滿了,所以事先騰一下硬碟也是有必要的。
壓測結果含義
- 正確/錯誤交易數:如果壓測結果包含很多錯誤或超時的交易,那麼本次壓測的意義不大。一般來說達到99%及以上的正確率,對業務才有意義。
- TPS(Transactions Per Second):每秒處理交易數,即區塊鏈處理此型別交易的效能。
壓測操作
使用已有壓測程式Java-SDK-Demo
FISCO BCOS提供了基於 Java-SDK實現的壓測程式:Java-SDK-Demo。
*舊版本中提供了基於Caliper的壓測程式,歡迎各位開發者持續優化Caliper壓測程式。在本文,更推薦使用Java-SDK-Demo。
Java-SDK-Demo Github地址
- 壓測 FISCO BCOS 2+ 版本:
https://github.com/FISCO-BCOS...
- 壓測 FISCO BCOS 3+ 版本:
https://github.com/FISCO-BCOS...
壓測場景
- 轉賬場景
- KVTable場景
- DMC場景
- 更多請檢視壓測程式目錄
壓測方法
參考專案下的README
操作例項
本操作以 Java-SDK-demo 中的轉賬場景進行舉例。
- 轉賬合約:ParallelOk.sol
- 壓測程式:ParallelOkPerf.java
步驟一:檢視壓測命令
*命令中提示的[tps]實際含義為QPS,即該壓測程式的交易傳送速率。
$ cd java-sdk-demo/dist/
$ java -cp 'conf/:lib/*:apps/*' org.fisco.bcos.sdk.demo.perf.ParallelOkPerf
Usage:
===== ParallelOk test===========
java -cp 'conf/:lib/*:apps/*' org.fisco.bcos.sdk.demo.perf.ParallelOkPerf [parallelok] [groupId] [add] [count] [tps] [file] [enableDAG].
java -cp 'conf/:lib/*:apps/*' org.fisco.bcos.sdk.demo.perf.ParallelOkPerf [parallelok] [groupId] [transfer] [count] [tps] [file] [enableDAG].
步驟二:執行壓測程式
轉賬場景壓測的操作分為兩步:
- 準備:批量生成轉賬使用者並初始化使用者金額(add)
*執行後,生成使用者列表檔案user1000.txt,下一步會用到。
# java -cp 'conf/:lib/*:apps/*' org.fisco.bcos.sdk.demo.perf.ParallelOkPerf parallelok] [groupId] [add] [count] [tps] [file] [enableDAG]
# 引數:壓測parallelok合約,群組group0,操作是新增使用者add,使用者數1000,qps=1000,要生成的使用者列表檔名,啟動交易並行執行
java -cp 'conf/:lib/*:apps/*' org.fisco.bcos.sdk.demo.perf.ParallelOkPerf parallelok group0 add 1000 1000 user1000.txt true
- 壓測:使用者間兩兩轉賬(transfer)
*可不斷重複此步驟,調整引數進行壓測。
# java -cp 'conf/:lib/*:apps/*' org.fisco.bcos.sdk.demo.perf.ParallelOkPerf [parallelok] [groupId] [transfer] [count] [tps] [file] [enableDAG]
# 引數:壓測parallelok合約,群組group0,操作時使用者轉賬transfer,總交易數10000,qps=1000,使用的使用者列表檔案,啟動交易並行執行
java -cp 'conf/:lib/*:apps/*' org.fisco.bcos.sdk.demo.perf.ParallelOkPerf parallelok group0 transfer 10000 1000 user1000.txt true
步驟三:檢視結果
TPS
- 包括錯誤交易:TPS(include error requests)
- 不包括錯誤交易:TPS(exclude error requests)
正確/錯誤交易數
validation:
user count is 1000
verify_success count is 1000
verify_failed count is 0
完整結果
Total transactions: 10000
Total time: 12676ms
TPS(include error requests): 788.8923950773114
TPS(exclude error requests): 788.8923950773114
Avg time cost: 1221ms
Error rate: 0.0%
Time area:
0 < time < 50ms : 21 : 0.21%
50 < time < 100ms : 1559 : 15.590000000000002%
100 < time < 200ms : 2460 : 24.6%
200 < time < 400ms : 318 : 3.18%
400 < time < 1000ms : 1562 : 15.620000000000001%
1000 < time < 2000ms : 1194 : 11.940000000000001%
2000 < time : 2886 : 28.860000000000003%
===================================================================
validation:
user count is 1000
verify_success count is 1000
verify_failed count is 0
壓測自定義合約
開發壓測程式,壓測自定義合約,與開發一個區塊鏈應用一樣,可參考區塊鏈應用開發文件,參考仿寫即可。
以Ok.sol為例,該合約包含的是一個基礎的鏈上資產轉讓邏輯,是比較精簡的合約,適合用來檢驗鏈的基本處理能力。如果你的業務邏輯較為複雜,首先請清晰地理解這一點:合約邏輯越複雜,TPS越低。(所以我們推薦鏈上的事務儘量簡潔,只包含需要多方共識的核心事務。)
- 找出被壓測的合約(Ok.sol);
- 編譯合約生成java程式碼(Ok.java),並整合入Java-SDK-Demo中;
- 編寫壓測程式(PerformanceOk.java);
- 編譯程式碼並部署到你的壓測環境;
- 壓測,且保證所有的交易結果都是正常的,錯誤的交易結果使壓測意義不大。
所有開發均在Java-SDK-Demo中進行,需開發的三個檔案及目錄結構如下:
- 合約:Ok.sol
- 合約編譯出的Java程式碼:Ok.java
- 壓測程式:PerformanceOk.java
java-sdk-demo/src/main/java/org/fisco/bcos/sdk/demo
├── contract
│ ├── Ok.java
│ └── sol
│ └── Ok.sol
└── perf
└── PerformanceOk.java
效能提升技巧
當你辛辛苦苦地完成了一次壓測,發現結果不是很滿意,那麼就要回過頭從“調參”一節重新開始了。這裡再強調一些關鍵技巧,可以讓你對壓測過程有更強的把控能力。
- 環境:在壓測的過程中,密切觀察壓測客戶端和鏈的環境引數。包括:
CPU利用率,保證多個CPU的核都儘量跑滿;
網路流量,判斷網速是否已成為瓶頸;
硬碟IO情況(尤其是IO Wait指標),判斷是否達到了儲存能力的瓶頸;
記憶體,一般不會有太大的問題,但極端情況下,如果記憶體不足,壓測程式有可能會掛住。
以上觀察方法,都可以用基本的Linux(或對應作業系統)基礎指令,作為壓測執行者,對作業系統一定要足夠熟練,對指令列印的資訊要有足夠理解。
- 優化合約邏輯:如減少合約介面引數,慎用陣列、Mapping等複雜的資料結構,精簡合約裡的計算邏輯、判斷邏輯等,減少不必要的事件(Event),對大的資料考慮是否可以只將資料的雜湊上鍊;確認是否可以採用DAG並行合約引擎。還有一個大殺器,就是採用FISCO BCOS預編譯合約實現合約邏輯,對追求極致效能的開發者,非常管用。
- 關注日誌:包括壓測客戶端的日誌,節點的日誌,以及系統日誌,尤其是裡面是否有發生錯誤和警告,一旦出現異常,則應立刻針對性地處理,不然有可能影響壓測結果。程式日誌裡一般會有詳細描述資訊,可以參照描述先做本地分析。
- 高效交流:如果要在社群裡諮詢壓測問題,建議把上面提到的配置先做充分檢查,記錄壓測過程的軟硬體指標,說清楚合約複雜度,先思考一下是否有序列、並行相關的問題和優化空間,並收集相關的日誌資訊,然後用多個截圖或整合文件的方式一次性把問題發給社群小助手或其他專家小夥伴,以便高效和深入地探討。
「FAQ」
Q FISCO BCOS在什麼環境下壓測達到2萬以上TPS?
A 共識節點分別部署在單個伺服器上,每臺伺服器24核32G記憶體,萬兆網的配置,在鏈引數得到合理優化、合約平行計算的基礎上,可以實現數萬以上TPS。
Q 我的環境下只能壓到1K,如何提升呢?
A 不同的合約對結果影響很大,有的合約在最好的硬體上可能也只能跑幾百TPS,或者有一些坑被踩到了,比如是否同步呼叫合約、交易池開得太小等。可參考本文【壓測技巧】,持續優化。
Q 我的CPU沒跑滿,是什麼原因造成的?
A 最常見的原因是QPS沒給夠,其他的原因可能有:區塊打包的交易數太少,可調大區塊打包交易數;未採用並行合約;合約邏輯中儲存量過大,儲存成為瓶頸。
Q 我調大了QPS,但出現了很多錯誤交易,如何調整呢?
A QPS遠大於實際處理的TPS,造成大量交易快取在交易池中超時了,在壓測中只保證QPS僅略大於TPS即可。
Q 採用Raft共識演算法是不是比PBFT效能要高一些?
A 共識演算法對TPS的影響很小,瓶頸在執行與儲存。總的來說,壓測過程是對效能的一種極致追求,不僅僅是個力氣活,需要對作業系統、區塊鏈系統的原理都有足夠了解,熟悉各種引數配置,知道如何去收集資料、分析問題、找瓶頸和突破瓶頸,一次壓測裡可能會有多次的反覆,最終得到理想的結果,會是一種成就和喜悅。祝你的應用速度和規模都插翅騰飛。
參考連結
壓測程式目錄:
https://github.com/FISCO-BCOS...
ParallelOk.sol:
https://github.com/FISCO-BCOS...
ParallelOkPerf.java:
https://github.com/FISCO-BCOS...
區塊鏈應用開發文件:
https://fisco-bcos-documentat...
Ok.sol:
https://github.com/FISCO-BCOS...
PerformanceOk.java:
https://github.com/FISCO-BCOS...
編譯合約生成java程式碼:
https://fisco-bcos-documentat...
FISCO BCOS配置文件:
https://fisco-bcos-documentat...
預編譯合約:
https://fisco-bcos-documentat...
並行合約開發方法:
https://fisco-bcos-documentat...
瞭解更多幹貨內容,請關注FISCO BCOS開源社群公眾號,訪問FISCO BCOS程式碼倉庫可下載專案所有原始碼:https://github.com/FISCO-BCOS/FISCO-BCOS,歡迎點選頁面右上角star收藏,獲取最新版本。