一文說清FISCO BCOS性能壓測(附實(shí)例教程)
“我的區(qū)塊鏈能跑多少TPS?”“能不能達(dá)到‘官方’所說的峰值?”“為啥總是壓不上去?是我的機(jī)器不夠好嗎?”
本文分別從原理、實(shí)操和技巧三個(gè)方面,為大家提供了詳盡的FISCO BCOS性能壓測指引,結(jié)合實(shí)例進(jìn)行演示,總結(jié)出壓測實(shí)用技巧與常見問題,以便大家更好地提升性能。
壓測原理
壓測這事,原理其實(shí)不復(fù)雜,起一個(gè)或一堆區(qū)塊鏈客戶端,先往鏈上部署一個(gè)用來壓測的合約或者需要評估性能的智能合約,然后卯足了勁往鏈上“并發(fā)”發(fā)送交易,收到區(qū)塊鏈返回的交易執(zhí)行結(jié)果(交易回執(zhí))后,統(tǒng)計(jì)出TPS。
由于區(qū)塊鏈分布式網(wǎng)絡(luò)廣播、交易排隊(duì)打包、共識確認(rèn)等流程還是比較漫長的,中間充滿了技術(shù)細(xì)節(jié),往往導(dǎo)致結(jié)果不如預(yù)期,這就需要在環(huán)境、參數(shù)、壓測程序以及合約邏輯等方面下功夫,才能得到理想的結(jié)果(把計(jì)算資源用到極致)、以及確切的結(jié)果(我的環(huán)境峰值就這么高了)。

??深入壓測細(xì)節(jié)
壓測前先“調(diào)參”
總交易數(shù):壓測程序在一次壓測中總共發(fā)送的交易數(shù)量。強(qiáng)調(diào)一下,如果沒有達(dá)到一定數(shù)量級的交易,壓測結(jié)果沒有統(tǒng)計(jì)含義。比如實(shí)際TPS應(yīng)該可以達(dá)到5000,那么只發(fā)幾千到一兩萬交易的話,因?yàn)槌绦騿?dòng)和停止等邊界條件影響,結(jié)果意義不大,至少超過兩個(gè)數(shù)量級的交易數(shù)(比如10萬筆、整個(gè)過程持續(xù)1分鐘以上),才能看出平穩(wěn)處理階段的TPS表現(xiàn)。
QPS(Queries Per Second):每秒請求數(shù),即壓測客戶端發(fā)送交易的速率。形象地說就是:壓測客戶端能不能“喂飽”鏈節(jié)點(diǎn),比如鏈的TPS性能在萬級,那么一個(gè)壓測客戶端的發(fā)送能力是否足夠,要具體評估,一個(gè)不夠,就要起多個(gè)壓測客戶端,而且每個(gè)客戶端發(fā)送的模式應(yīng)該是異步的,如果每次都是發(fā)送一個(gè)交易然后同步等結(jié)果再發(fā)下一個(gè),是很難“喂飽”區(qū)塊鏈節(jié)點(diǎn)的(如何確保異步,參見SDK的接口定義)。
但是,QPS也不能過大,當(dāng)QPS過大時(shí),會(huì)讓交易堆積在交易池中。這些堆積的交易不能被立即執(zhí)行,使得測出的TPS會(huì)小于實(shí)際的TPS。
合約復(fù)雜度:合約的復(fù)雜度對TPS結(jié)果會(huì)有極大影響。合約復(fù)雜度簡單的理解就是代碼量(對應(yīng)指令數(shù))、數(shù)據(jù)量(具體來說就是合約里牽涉的狀態(tài)數(shù)據(jù)量),還有很重要的一點(diǎn)是合約是否支持并行事務(wù)邏輯。并行才能用盡服務(wù)器資源,要達(dá)到并行處理效果,除了上一條所說的壓測客戶端需要異步發(fā)送之外,F(xiàn)ISCO BCOS的合約是支持DAG并行計(jì)算的,一個(gè)普通合約,如果在事務(wù)上可以支持并行,打開DAG并行設(shè)置,才能用盡服務(wù)器上所有的CPU計(jì)算能力,否則實(shí)際上也是在“串行”處理,只用了一個(gè)CPU,效果肯定不會(huì)太好。 DAG并行合約開發(fā)參見: https://fisco-bcos-documentation.readthedocs.io/zh_CN/latest/docs/manual/transaction_parallel.html)
鏈參數(shù)配置:?有幾個(gè)關(guān)鍵的鏈參數(shù)和性能表現(xiàn)相關(guān),包括多長時(shí)間出一個(gè)區(qū)塊,一個(gè)區(qū)塊里能打包多少個(gè)交易。在壓測場景里,這幾個(gè)數(shù)字要配置得比較合適,我們默認(rèn)500ms嘗試將交易池(大小:[tx_pool].limit)中的交易打包成一個(gè)區(qū)塊(打包間隔:[consensus]. min_block_generation_time),每個(gè)默認(rèn)最多1000筆交易(區(qū)塊最大交易數(shù):tx_count_limit)。
同時(shí),節(jié)點(diǎn)會(huì)自動(dòng)保證在1秒內(nèi)出一個(gè)塊。如果出當(dāng)前區(qū)塊的時(shí)間大于1秒,下一個(gè)區(qū)塊會(huì)少打包一些交易,若小于1秒,會(huì)根據(jù)設(shè)置的區(qū)塊最大交易數(shù)上限盡量打包交易。若單純?yōu)榱藟簻y,推薦將打包間隔盡可能調(diào)小,并反復(fù)調(diào)節(jié)區(qū)塊最大交易數(shù),讓出塊時(shí)間均勻穩(wěn)定的同時(shí),盡量逼近最大值。此處推薦將打包間隔設(shè)置為1ms,區(qū)塊最大交易數(shù)最低為10000筆起步,根據(jù)實(shí)際結(jié)果向上調(diào)整??蓞⒖嘉哪癋ISCO BCOS 配置文檔”進(jìn)行配置。
硬件配置:如果想要得到盡量高的TPS,要采用性能更好的硬件。具體而言就是服務(wù)器核數(shù)越多越好,內(nèi)存越寬裕越好;一定要用高速機(jī)械硬盤或SSD硬盤,慎用相對低速的網(wǎng)絡(luò)存儲(chǔ)設(shè)備,硬盤的IO速度對鏈的區(qū)塊和狀態(tài)寫入速度有巨大的影響;網(wǎng)絡(luò)帶寬越大延遲越低越好,保證壓測程序和鏈節(jié)點(diǎn)之間的網(wǎng)絡(luò),以及節(jié)點(diǎn)和節(jié)點(diǎn)之間的網(wǎng)絡(luò)是暢通高效的。
其他調(diào)整:壓測客戶端和鏈的日志級別最好開到Error級,盡量地減少日志輸出量。環(huán)境里如有其他占用資源(CPU、內(nèi)存、硬盤網(wǎng)絡(luò)等)的程序,不妨?xí)簳r(shí)退出。之前有開發(fā)者的壓測把硬盤寫滿了,所以事先騰一下硬盤也是有必要的。
壓測結(jié)果含義
正確/錯(cuò)誤交易數(shù):如果壓測結(jié)果包含很多錯(cuò)誤或超時(shí)的交易,那么本次壓測的意義不大。一般來說達(dá)到99%及以上的正確率,對業(yè)務(wù)才有意義。 TPS(Transactions Per Second):每秒處理交易數(shù),即區(qū)塊鏈處理此類型交易的性能。


壓測操作
??使用已有壓測程序Java-SDK-Demo
壓測 FISCO BCOS 2+ 版本:
https://github.com/FISCO-BCOS/java-sdk-demo/tree/release-2.8.0 壓測 FISCO BCOS 3+ 版本:
https://github.com/FISCO-BCOS/java-sdk-demo
壓測場景
轉(zhuǎn)賬場景 KVTable場景 DMC場景 更多請查看壓測程序目錄
壓測方法
參考項(xiàng)目下的README
轉(zhuǎn)賬合約:ParallelOk.sol 壓測程序:ParallelOkPerf.java
$ cd java-sdk-demo/dist/$ java -cp 'conf/:lib/*:apps/*' org.fisco.bcos.sdk.demo.perf.ParallelOkPerfUsage:===== 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].
步驟二:執(zhí)行壓測程序
# java -cp 'conf/:lib/*:apps/*' org.fisco.bcos.sdk.demo.perf.ParallelOkPerf parallelok] [groupId] [add] [count] [tps] [file] [enableDAG]# 參數(shù):壓測parallelok合約,群組group0,操作是添加用戶add,用戶數(shù)1000,qps=1000,要生成的用戶列表文件名,啟動(dòng)交易并行執(zhí)行java -cp 'conf/:lib/*:apps/*' org.fisco.bcos.sdk.demo.perf.ParallelOkPerf parallelok group0 add 1000 1000 user1000.txt true
# java -cp 'conf/:lib/*:apps/*' org.fisco.bcos.sdk.demo.perf.ParallelOkPerf [parallelok] [groupId] [transfer] [count] [tps] [file] [enableDAG]# 參數(shù):壓測parallelok合約,群組group0,操作時(shí)用戶轉(zhuǎn)賬transfer,總交易數(shù)10000,qps=1000,使用的用戶列表文件,啟動(dòng)交易并行執(zhí)行java -cp 'conf/:lib/*:apps/*' org.fisco.bcos.sdk.demo.perf.ParallelOkPerf parallelok group0 transfer 10000 1000 user1000.txt true
步驟三:查看結(jié)果
TPS
包括錯(cuò)誤交易:TPS(include error requests) 不包括錯(cuò)誤交易:TPS(exclude error requests)
正確/錯(cuò)誤交易數(shù)
validation:user count is 1000verify_success count is 1000verify_failed count is 0
完整結(jié)果
Total transactions: 10000Total time: 12676msTPS(include error requests): 788.8923950773114TPS(exclude error requests): 788.8923950773114Avg time cost: 1221msError 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 1000verify_success count is 1000verify_failed count is 0
??壓測自定義合約
??
1. 找出被壓測的合約(Ok.sol);
2.?編譯合約生成java代碼(Ok.java),并集成入Java-SDK-Demo中;
3. 編寫壓測程序(PerformanceOk.java);
4. 編譯代碼并部署到你的壓測環(huán)境;
5. 壓測,且保證所有的交易結(jié)果都是正常的,錯(cuò)誤的交易結(jié)果使壓測意義不大。
合約: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利用率,保證多個(gè)CPU的核都盡量跑滿;
網(wǎng)絡(luò)流量,判斷網(wǎng)速是否已成為瓶頸;
硬盤IO情況(尤其是IO Wait指標(biāo)),判斷是否達(dá)到了存儲(chǔ)能力的瓶頸;
內(nèi)存,一般不會(huì)有太大的問題,但極端情況下,如果內(nèi)存不足,壓測進(jìn)程有可能會(huì)掛住。
以上觀察方法,都可以用基本的Linux(或?qū)?yīng)操作系統(tǒng))基礎(chǔ)指令,作為壓測執(zhí)行者,對操作系統(tǒng)一定要足夠熟練,對指令打印的信息要有足夠理解。
2.?優(yōu)化合約邏輯:如減少合約接口參數(shù),慎用數(shù)組、Mapping等復(fù)雜的數(shù)據(jù)結(jié)構(gòu),精簡合約里的計(jì)算邏輯、判斷邏輯等,減少不必要的事件(Event),對大的數(shù)據(jù)考慮是否可以只將數(shù)據(jù)的哈希上鏈;確認(rèn)是否可以采用DAG并行合約引擎。還有一個(gè)大殺器,就是采用FISCO BCOS預(yù)編譯合約實(shí)現(xiàn)合約邏輯,對追求極致性能的開發(fā)者,非常管用。
3.?關(guān)注日志:包括壓測客戶端的日志,節(jié)點(diǎn)的日志,以及系統(tǒng)日志,尤其是里面是否有發(fā)生錯(cuò)誤和警告,一旦出現(xiàn)異常,則應(yīng)立刻針對性地處理,不然有可能影響壓測結(jié)果。程序日志里一般會(huì)有詳細(xì)描述信息,可以參照描述先做本地分析。
4.?高效交流:如果要在社群里咨詢壓測問題,建議把上面提到的配置先做充分檢查,記錄壓測過程的軟硬件指標(biāo),說清楚合約復(fù)雜度,先思考一下是否有串行、并行相關(guān)的問題和優(yōu)化空間,并收集相關(guān)的日志信息,然后用多個(gè)截圖或整合文檔的方式一次性把問題發(fā)給社區(qū)小助手或其他專家小伙伴,以便高效和深入地探討。
「FAQ」
---
?Q??FISCO BCOS在什么環(huán)境下壓測達(dá)到2萬以上TPS?咨詢交流更多問題,請掃碼添加【小助手】加入官方技術(shù)交流群,與上萬開發(fā)達(dá)人共同探討。
fiscobcosfan
??參考鏈接
壓測程序目錄:
ParallelOk.sol:
https://github.com/FISCO-BCOS/java-sdk-demo/blob/main/src/main/java/org/fisco/bcos/sdk/demo/contract/sol/ParallelOk.sol
ParallelOkPerf.java:
https://github.com/FISCO-BCOS/java-sdk-demo/blob/main/src/main/java/org/fisco/bcos/sdk/demo/perf/ParallelOkPerf.java
區(qū)塊鏈應(yīng)用開發(fā)文檔:
https://fisco-bcos-documentation.readthedocs.io/zh_CN/latest/docs/tutorial/sdk_application.html
Ok.sol:
https://github.com/FISCO-BCOS/java-sdk-demo/blob/main/src/main/java/org/fisco/bcos/sdk/demo/contract/sol/Ok.sol
PerformanceOk.java:
https://github.com/FISCO-BCOS/java-sdk-demo/blob/main/src/main/java/org/fisco/bcos/sdk/demo/perf/PerformanceOk.java
編譯合約生成java代碼:
https://fisco-bcos-documentation.readthedocs.io/zh_CN/latest/docs/tutorial/sdk_application.html#id6
FISCO BCOS配置文檔:
https://fisco-bcos-documentation.readthedocs.io/zh_CN/latest/docs/manual/configuration.html
預(yù)編譯合約:
https://fisco-bcos-documentation.readthedocs.io/zh_CN/latest/docs/manual/precompiled_contract.html
并行合約開發(fā)方法:
https://fisco-bcos-documentation.readthedocs.io/zh_CN/latest/docs/manual/transaction_parallel.html
延展閱讀
FISCO BCOS的代碼完全開源且免費(fèi)
下載地址↓↓↓
https://github.com/FISCO-BCOS/FISCO-BCOS



