发布时间:2023-03-10 来源:本站
“我的区块链能跑多少TPS?”“能不能达到‘官方’所说的峰值?”“为啥总是压不上去?是我的机器不够好吗?”
本文分别从原理、实操和技巧三个方面,为大家提供了详尽的FISCO BCOS性能压测指引,结合实例进行演示,总结出压测实用技巧与常见问题,以便大家更好地提升性能。
压测原理
压测这事,原理其实不复杂,起一个或一堆区块链客户端,先往链上部署一个用来压测的合约或者需要评估性能的智能合约,然后卯足了劲往链上“并发”发送交易,收到区块链返回的交易执行结果(交易回执)后,统计出TPS。
由于区块链分布式网络广播、交易排队打包、共识确认等流程还是比较漫长的,中间充满了技术细节,往往导致结果不如预期,这就需要在环境、参数、压测程序以及合约逻辑等方面下功夫,才能得到理想的结果(把计算资源用到极致)、以及确切的结果(我的环境峰值就这么高了)。
▍深入压测细节
压测前先“调参”
总交易数:压测程序在一次压测中总共发送的交易数量。强调一下,如果没有达到一定数量级的交易,压测结果没有统计含义。比如实际TPS应该可以达到5000,那么只发几千到一两万交易的话,因为程序启动和停止等边界条件影响,结果意义不大,至少超过两个数量级的交易数(比如10万笔、整个过程持续1分钟以上),才能看出平稳处理阶段的TPS表现。
QPS(Queries Per Second):每秒请求数,即压测客户端发送交易的速率。形象地说就是:压测客户端能不能“喂饱”链节点,比如链的TPS性能在万级,那么一个压测客户端的发送能力是否足够,要具体评估,一个不够,就要起多个压测客户端,而且每个客户端发送的模式应该是异步的,如果每次都是发送一个交易然后同步等结果再发下一个,是很难“喂饱”区块链节点的(如何确保异步,参见SDK的接口定义)。
但是,QPS也不能过大,当QPS过大时,会让交易堆积在交易池中。这些堆积的交易不能被立即执行,使得测出的TPS会小于实际的TPS。
https://fisco-bcos-documentation.readthedocs.io/zh_CN/latest/docs/manual/transaction_parallel.html)
链参数配置: 有几个关键的链参数和性能表现相关,包括多长时间出一个区块,一个区块里能打包多少个交易。在压测场景里,这几个数字要配置得比较合适,我们默认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 2+ 版本:
压测 FISCO BCOS 3+ 版本:
https://github.com/FISCO-BCOS/java-sdk-demo
压测场景
●转账场景
●KVTable场景
●DMC场景
●更多请查看压测程序目录
压测方法
参考项目下的README
本操作以 Java-SDK-demo 中的转账场景进行举例。
●转账合约:ParallelOk.sol
●压测程序:ParallelOkPerf.java
$ 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].
步骤二:执行压测程序
# 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
# 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
正确/错误交易数
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
▍压测自定义合约
1. 找出被压测的合约(Ok.sol);
2. 编译合约生成java代码(Ok.java),并集成入Java-SDK-Demo中;
3. 编写压测程序(PerformanceOk.java);
4. 编译代码并部署到你的压测环境;
5. 压测,且保证所有的交易结果都是正常的,错误的交易结果使压测意义不大。
所有开发均在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(或对应操作系统)基础指令,作为压测执行者,对操作系统一定要足够熟练,对指令打印的信息要有足够理解。
2. 优化合约逻辑:如减少合约接口参数,慎用数组、Mapping等复杂的数据结构,精简合约里的计算逻辑、判断逻辑等,减少不必要的事件(Event),对大的数据考虑是否可以只将数据的哈希上链;确认是否可以采用DAG并行合约引擎。还有一个大杀器,就是采用FISCO BCOS预编译合约实现合约逻辑,对追求极致性能的开发者,非常管用。
3. 关注日志:包括压测客户端的日志,节点的日志,以及系统日志,尤其是里面是否有发生错误和警告,一旦出现异常,则应立刻针对性地处理,不然有可能影响压测结果。程序日志里一般会有详细描述信息,可以参照描述先做本地分析。
4. 高效交流:如果要在社群里咨询压测问题,建议把上面提到的配置先做充分检查,记录压测过程的软硬件指标,说清楚合约复杂度,先思考一下是否有串行、并行相关的问题和优化空间,并收集相关的日志信息,然后用多个截图或整合文档的方式一次性把问题发给社区小助手或其他专家小伙伴,以便高效和深入地探讨。
「FAQ」
---
Q FISCO BCOS在什么环境下压测达到2万以上TPS?
参考链接
压测程序目录:
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
区块链应用开发文档:
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
预编译合约:
https://fisco-bcos-documentation.readthedocs.io/zh_CN/latest/docs/manual/precompiled_contract.html
并行合约开发方法:
https://fisco-bcos-documentation.readthedocs.io/zh_CN/latest/docs/manual/transaction_parallel.html
------
本文转自:FISCO BCOS 开源社区公众号,欢迎加小助手微信【FISCOBCOS010】进技术交流群。
点击阅读原文