2022 Go生态圈 rpc 框架 Benchmark [订正版]
2022 Go生态圈 rpc 框架 Benchmark [订正版]
距离上一次2021年Go生态圈rpc框架benchmark的测试整整一年了。一年来,各个RPC框架也获得长足的进展,rpcx也在众多网友的支持下做了一些有益的优化和精简,所以是时候再做一次国内几个常用框架的性能比较了。
https://colobu.com/2022/07/31/2022-rpc-frameworks-benchmarks/
鸟窝老师,请问压测数据已经按照 https://github.com/rpcxio/rpcx-benchmark/issues/13 更新过了吗,从结果看不太对。如 3 所说
Kitex 的连接多路复用大部分场景只需要1个连接即可,默认也是一个连接,单实例压测配置较多连接反而会带来性能劣化。rpcx和arpc需要10个client发压提升吞吐,而Kitex连接多路复用可以用更少的资源达到吞吐和延迟表现较好的状态。如果只对比10个client或多个连接发压作为结果也不合理,实际的应用场景中也是共享一个client而不是多个。
如果一定要对齐使用多个client,那建议增加一组单client对比,相比多client,单client更符合实际应用。 另外,这个测试存在一定的波动性,建议多测试几组,或者增加发压请求数,1000000总请求数在并发大时波动明显,可以改为10000000
rpc最重要的还是序列化吧,测试只测了网络方面的。还有就是std_rpc不是用的gob序列化的吗?
鸟窝老师今年的测试更全面,感谢辛苦付出!
其实以往的的 P99.9 对比是不太科学的,比如 A 吞吐量 2w, B 吞吐量 1.5w,那么很可能是 A 的前 1.5w 个都比 B 快,剩下那 5k 完全是比 B 多处理的请求,但用来做 P99.9 却是取的 A 的第 19980 个请求的延时。
鸟窝老师这次的这个对比中包括了固定吞吐量下的 P99.9 对比,降低了这个误差。
但固定请求量本身也是限制了框架的处理能力,如果是按照真实的吞吐下的各个框架的不同吞吐的延时可能算是更进一步,比如: ABCDE 框架各 15000,16000,17000,18000,19000/s的吞吐,再对比各框架在各阶梯吞吐下的延时。
Kitex 的连接多路复用大部分场景只需要1个连接即可,默认也是一个连接,单实例压测配置较多连接反而会带来性能劣化。rpcx和arpc需要10个client发压提升吞吐,而Kitex连接多路复用可以用更少的资源达到吞吐和延迟表现较好的状态。如果只对比10个client或多个连接发压作为结果也不合理,实际的应用场景中也是共享一个client而不是多个。
@YangruiEmma hi大佬,时间过的好快,转眼又是一年
单个连接也是各参考指标,但主要是侧重于测试cleint side。 实际生产中更侧重的是server承载多连接的性能。
顺便请教下kitex-benchmark的问题。 我在跑kitex-benchmark测试时发现kitex并不比arpc数据好,但kitex-mux能比arpc数据好。后来翻看代码,kitex-mux的连接池设置跟其他框架不一样、注释中说设置为2最好所以设置的是2,但其实改成和其他框架一样后好像kitex-mux仍然数据更好。所以这里顺便请教下,kitex-mux与kitex有什么不同?字节生产环境使用的是kitex还是kitex-mux?kitex-mux更强,为什么不把kitex废弃、直接使用kitex-mux,有什么其他原因吗(比如针对cpu消耗、io消耗等不同业务类型的稳定性不同)?
kitex-benchmark测试的主要是少量连接数,这与实际生产场景不太一致,所以我觉得kitex-benchmark还是加上更多连接的测试结果会准确些。
对于请求的处理,绝大多数go rpc框架的做法是异步处理每个请求:
- 一些框架没使用协程池、每个请求都创建一个协程单独处理,这样的问题是对协程频繁创建消耗、以及海量请求时可能系统同时存在大量协程带来硬件压力
- 另一些框架引入了协程池,用协程池来异步处理这些请求,从而达到协程数量可控进而硬件消耗可控的目标。
但不管是否使用协程池,这种统一异步处理的方式,还是有些缺点:
- 对于handler内cpu消耗型并且耗时非常短的请求,异步处理时协程切换的额外消耗相比于handler本身的逻辑消耗可能会比例较大、不如直接同步处理划算
- 其他的go rpc框架通常都是handler返回了就请求结束了,不方便与其他模块进行更灵活的同步异步搭配。arpc不开启pool的情况下,handler返回并不等于调用结束,而是ctx.Write响应后才是结束,所以更方便
去年我也聊过,kitex-benchmark中的测试主要是cpu消耗类型,这一点上arpc使用了异步响应的模式其实并不能最大化性能。因为arpc支持不同粒度的同步异步响应机制,应用层根据自己实际情况选择异步策略来最大化性能。这种cpu消耗类型的rpc路由/方法,arpc可以设置为同步响应,则吞吐性能可以远高于异步响应。所以从这个角度讲,kitex-benchmark的测试中并没有完全发挥出arpc的性能。
看了测评心血来潮,打算再试着做一波性能优化,大概尝试以下:
- 废弃bufio的read,直接read到buffer后在buffer上取一个完整消息段出来就是单个message,也就是zero copy,避免从bufio再到message的拷贝,不确定是否能对性能有所帮助,以及稳定性,因为这样的话pool相关的也需要做相应的修改
- 写用bufio+chan struct{}通知flush,因为现在的写是单个消息拼接好了一段buf然后传递给chan去排队写,虽然有batch write的优化,但这里仍然是需要一次拷贝,而如果拼接消息的时候就直接写入到bufio里去,后续的flush就不需要再拷贝了
@smallnest 鸟窝老师,咱们的框架的IO部分比较像,也可以考虑下这两点相关的
看了测评心血来潮,打算再试着做一波性能优化,大概尝试以下:
- 废弃bufio的read,直接read到buffer后在buffer上取一个完整消息段出来就是单个message,也就是zero copy,避免从bufio再到message的拷贝,不确定是否能对性能有所帮助,以及稳定性,因为这样的话pool相关的也需要做相应的修改
- 写用bufio+chan struct{}通知flush,因为现在的写是单个消息拼接好了一段buf然后传递给chan去排队写,虽然有batch write的优化,但这里仍然是需要一次拷贝,而如果拼接消息的时候就直接写入到bufio里去,后续的flush就不需要再拷贝了
@smallnest 鸟窝老师,咱们的框架的IO部分比较像,也可以考虑下这两点相关的
想了下,arpc提供的编码中间件是需要以Message为单位的,所以 2 里的zero copy是没什么希望俩,但是bufio+chan flush还是可以再试试,我到时候对比下看看
今天发现个 frpc 很快,单拼 benchmark 的话,能把我 arpc 拉开一截差距: https://github.com/loopholelabs/frpc-go-benchmarks
但是它这个 rpc 主要就是 rpc,没有那么丰富的功能比如中间件,而且它的协议头只有8字节,单个连接 message id只有两字节的 uint16滚动,即最多 65535 个,在高并发的场景,某个消息如果处理时间较长,这个id滚动一轮了就和把上一轮相同id的 message 混了,不够严谨,所以也没有太大可比性。我前面说的两点优化中的2就是参考它的,但仔细想了下,提升的可能性不大。我继续看看它这个还有没有额外的借鉴之处
其实标准库如果不是用 gob,速度应该也是足够快的,gob的性能太拉跨了
最近做了个 golang websocket 框架的 benchmark 仓库,包括 4c/2g VM 下 nbio 的 websocket百万连接测试,参考字节引入的 cpu mem 消耗统计,但使用了跨平台的库。 压测的过程中有框架设置了 SetNodelay(false),对于单连接上多并发写入的场景,数据提升比较大:我的VM里 arpc TCP 默认参数 SetNodelay(true) 22w tps,SetNodelay(false) 后可以跑到 38w tps。
对于实际场景,低峰时段,SetNoDelay(false) 可能会使响应略降但可以接受,对于高峰时段并发写入多的场景可能会有一定的提升,仅供参考。
另外刚才给ws的压测在 eer分支 增加了CPU能效比的字段: ·BenchEcho·的·EER·是单位CPU每秒Echo次数 ·BenchRate·的·EchoEER·:单位CPU收包每秒,只统计了收包量、不统计发包量,免得有发出去很多但框架没有成功回写。
例如:
20230810 13:08.48.203 [BenchEcho] Report
| Framework | TPS | EER | Min | Avg | Max | TP50 | TP75 | TP90 | TP95 | TP99 | Used | Total | Success | Failed | Conns | Concurrency | Payload | CPU Min | CPU Avg | CPU Max | MEM Min | MEM Avg | MEM Max |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| fasthttp | 242036 | 681.19 | 16.13us | 41.18ms | 145.56ms | 37.67ms | 42.09ms | 52.76ms | 56.44ms | 86.02ms | 8.26s | 2000000 | 2000000 | 0 | 10000 | 10000 | 1024 | 336.95 | 355.31 | 368.94 | 238.62M | 242.31M | 247.25M |
| gobwas | 190015 | 484.09 | 14.28us | 52.43ms | 210.09ms | 46.82ms | 62.26ms | 68.42ms | 75.05ms | 105.20ms | 10.53s | 2000000 | 2000000 | 0 | 10000 | 10000 | 1024 | 383.92 | 392.52 | 397.75 | 344.93M | 347.87M | 348.71M |
| gorilla | 247881 | 679.48 | 33.45us | 40.20ms | 157.03ms | 37.14ms | 40.75ms | 52.86ms | 55.11ms | 68.33ms | 8.07s | 2000000 | 2000000 | 0 | 10000 | 10000 | 1024 | 357.95 | 364.81 | 374.95 | 239.18M | 245.02M | 251.05M |
| gws | 226052 | 654.83 | 27.73us | 44.11ms | 153.75ms | 40.79ms | 47.71ms | 59.10ms | 64.23ms | 85.84ms | 8.85s | 2000000 | 2000000 | 0 | 10000 | 10000 | 1024 | 282.73 | 345.20 | 362.60 | 149.55M | 164.71M | 167.79M |
| gws_std | 249168 | 720.45 | 23.35us | 40.01ms | 172.71ms | 37.19ms | 40.24ms | 52.48ms | 55.44ms | 66.26ms | 8.03s | 2000000 | 2000000 | 0 | 10000 | 10000 | 1024 | 339.95 | 345.85 | 355.93 | 244.38M | 266.17M | 284.06M |
| hertz | 185152 | 559.46 | 11.94ms | 53.78ms | 208.36ms | 47.57ms | 62.76ms | 83.68ms | 95.49ms | 115.66ms | 10.80s | 2000000 | 2000000 | 0 | 10000 | 10000 | 1024 | 269.91 | 330.95 | 343.94 | 493.43M | 544.34M | 593.10M |
| hertz_std | 234164 | 616.49 | 31.55us | 42.53ms | 98.06ms | 39.43ms | 43.46ms | 55.69ms | 58.19ms | 70.64ms | 8.54s | 2000000 | 2000000 | 0 | 10000 | 10000 | 1024 | 373.88 | 379.83 | 389.81 | 322.72M | 324.46M | 328.27M |
| nbio_blocking | 256963 | 743.55 | 27.32us | 38.80ms | 81.61ms | 36.28ms | 38.56ms | 51.33ms | 53.08ms | 57.09ms | 7.78s | 2000000 | 2000000 | 0 | 10000 | 10000 | 1024 | 269.87 | 345.59 | 365.95 | 145.53M | 184.76M | 200.96M |
| nbio_mixed | 251894 | 714.91 | 32.65us | 39.58ms | 114.47ms | 36.92ms | 39.52ms | 51.68ms | 54.25ms | 60.89ms | 7.94s | 2000000 | 2000000 | 0 | 10000 | 10000 | 1024 | 333.59 | 352.34 | 366.48 | 158.31M | 201.41M | 223.63M |
| nbio_nonblocking | 202982 | 576.37 | 99.32us | 49.07ms | 205.38ms | 45.37ms | 62.14ms | 80.44ms | 91.45ms | 112.06ms | 9.85s | 2000000 | 2000000 | 0 | 10000 | 10000 | 1024 | 306.70 | 352.17 | 365.92 | 106.15M | 115.42M | 121.54M |
| nbio_std | 251264 | 759.59 | 21.39us | 39.68ms | 124.63ms | 36.89ms | 41.42ms | 52.18ms | 55.74ms | 63.90ms | 7.96s | 2000000 | 2000000 | 0 | 10000 | 10000 | 1024 | 308.95 | 330.79 | 366.75 | 164.85M | 185.62M | 193.23M |
| nettyws | 243512 | 688.03 | 24.43us | 40.95ms | 152.91ms | 38.09ms | 41.06ms | 52.94ms | 57.23ms | 75.34ms | 8.21s | 2000000 | 2000000 | 0 | 10000 | 10000 | 1024 | 347.84 | 353.93 | 371.94 | 157.30M | 167.14M | 175.78M |
| nhooyr | 198001 | 497.09 | 17.02us | 50.27ms | 153.99ms | 47.52ms | 53.44ms | 69.98ms | 74.21ms | 86.12ms | 10.10s | 2000000 | 2000000 | 0 | 10000 | 10000 | 1024 | 393.89 | 398.32 | 399.95 | 358.27M | 370.80M | 383.83M |
| quickws | 259693 | 829.90 | 26.71us | 38.39ms | 156.33ms | 35.63ms | 39.29ms | 51.04ms | 53.54ms | 71.92ms | 7.70s | 2000000 | 2000000 | 0 | 10000 | 10000 | 1024 | 215.66 | 312.92 | 356.61 | 117.07M | 117.07M | 117.07M |
20230810 13:08.48.204 [BenchRate] Report
| Framework | EchoEER | Duration | Packet Sent | Bytes Sent | Packet Recv | Bytes Recv | Conns | SendRate | Payload | CPU Min | CPU Avg | CPU Max | MEM Min | MEM Avg | MEM Max |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| fasthttp | 1884.90 | 10.00s | 7408680 | 7.07G | 7234813 | 6.90G | 10000 | 200 | 1024 | 324.06 | 383.83 | 400.76 | 252.93M | 276.39M | 304.63M |
| gobwas | 870.73 | 10.00s | 3609810 | 3.44G | 3239432 | 3.09G | 10000 | 200 | 1024 | 360.80 | 372.03 | 386.70 | 491.75M | 569.26M | 649.55M |
| gorilla | 2362.53 | 10.00s | 9350260 | 8.92G | 9350260 | 8.92G | 10000 | 200 | 1024 | 372.98 | 395.77 | 399.04 | 267.41M | 295.04M | 322.72M |
| gws | 2077.92 | 10.00s | 8511030 | 8.12G | 8261911 | 7.88G | 10000 | 200 | 1024 | 396.51 | 397.60 | 398.90 | 232.49M | 237.21M | 238.65M |
| gws_std | 2434.59 | 10.00s | 9965380 | 9.50G | 9735482 | 9.28G | 10000 | 200 | 1024 | 395.64 | 399.88 | 402.93 | 318.79M | 345.90M | 350.81M |
| hertz | 1272.08 | 10.00s | 5093950 | 4.86G | 4727336 | 4.51G | 10000 | 200 | 1024 | 326.54 | 371.62 | 395.66 | 656.71M | 1.29G | 1.57G |
| hertz_std | 2228.99 | 10.00s | 9135510 | 8.71G | 8877629 | 8.47G | 10000 | 200 | 1024 | 394.94 | 398.28 | 399.87 | 344.59M | 371.63M | 399.40M |
| nbio_blocking | 2297.96 | 10.00s | 9338210 | 8.91G | 9139458 | 8.72G | 10000 | 200 | 1024 | 390.58 | 397.72 | 399.80 | 203.03M | 207.05M | 208.39M |
| nbio_mixed | 2398.90 | 10.00s | 9730230 | 9.28G | 9514688 | 9.07G | 10000 | 200 | 1024 | 388.90 | 396.63 | 399.93 | 310.02M | 396.65M | 427.32M |
| nbio_nonblocking | 2044.85 | 10.00s | 8235200 | 7.85G | 8067792 | 7.69G | 10000 | 200 | 1024 | 392.77 | 394.54 | 397.40 | 324.86M | 428.45M | 462.98M |
| nbio_std | 2295.72 | 10.00s | 9336780 | 8.90G | 9071768 | 8.65G | 10000 | 200 | 1024 | 376.90 | 395.16 | 398.95 | 199.59M | 203.62M | 210.97M |
| nettyws | 2177.35 | 10.00s | 8924420 | 8.51G | 8673631 | 8.27G | 10000 | 200 | 1024 | 394.20 | 398.36 | 400.05 | 199.05M | 218.60M | 226.48M |
| nhooyr | 1273.67 | 10.00s | 5404580 | 5.15G | 5080615 | 4.85G | 10000 | 200 | 1024 | 396.91 | 398.90 | 400.62 | 399.86M | 432.51M | 464.41M |
| quickws | 2371.21 | 10.00s | 9427230 | 8.99G | 9295394 | 8.86G | 10000 | 200 | 1024 | 385.37 | 392.01 | 399.65 | 130.14M | 133.63M | 134.78M |