gitalk icon indicating copy to clipboard operation
gitalk copied to clipboard

2022 Go生态圈 rpc 框架 Benchmark [订正版]

Open utterances-bot opened this issue 3 years ago • 9 comments

2022 Go生态圈 rpc 框架 Benchmark [订正版]

距离上一次2021年Go生态圈rpc框架benchmark的测试整整一年了。一年来,各个RPC框架也获得长足的进展,rpcx也在众多网友的支持下做了一些有益的优化和精简,所以是时候再做一次国内几个常用框架的性能比较了。

https://colobu.com/2022/07/31/2022-rpc-frameworks-benchmarks/

utterances-bot avatar Aug 04 '22 03:08 utterances-bot

鸟窝老师,请问压测数据已经按照 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

YangruiEmma avatar Aug 04 '22 03:08 YangruiEmma

rpc最重要的还是序列化吧,测试只测了网络方面的。还有就是std_rpc不是用的gob序列化的吗?

lysShub avatar Aug 05 '22 02:08 lysShub

鸟窝老师今年的测试更全面,感谢辛苦付出!

lesismal avatar Oct 24 '22 05:10 lesismal

其实以往的的 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的吞吐,再对比各框架在各阶梯吞吐下的延时。

lesismal avatar Oct 24 '22 05:10 lesismal

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框架的做法是异步处理每个请求:

  1. 一些框架没使用协程池、每个请求都创建一个协程单独处理,这样的问题是对协程频繁创建消耗、以及海量请求时可能系统同时存在大量协程带来硬件压力
  2. 另一些框架引入了协程池,用协程池来异步处理这些请求,从而达到协程数量可控进而硬件消耗可控的目标。

但不管是否使用协程池,这种统一异步处理的方式,还是有些缺点:

  1. 对于handler内cpu消耗型并且耗时非常短的请求,异步处理时协程切换的额外消耗相比于handler本身的逻辑消耗可能会比例较大、不如直接同步处理划算
  2. 其他的go rpc框架通常都是handler返回了就请求结束了,不方便与其他模块进行更灵活的同步异步搭配。arpc不开启pool的情况下,handler返回并不等于调用结束,而是ctx.Write响应后才是结束,所以更方便

去年我也聊过,kitex-benchmark中的测试主要是cpu消耗类型,这一点上arpc使用了异步响应的模式其实并不能最大化性能。因为arpc支持不同粒度的同步异步响应机制,应用层根据自己实际情况选择异步策略来最大化性能。这种cpu消耗类型的rpc路由/方法,arpc可以设置为同步响应,则吞吐性能可以远高于异步响应。所以从这个角度讲,kitex-benchmark的测试中并没有完全发挥出arpc的性能。

lesismal avatar Oct 24 '22 05:10 lesismal

看了测评心血来潮,打算再试着做一波性能优化,大概尝试以下:

  1. 废弃bufio的read,直接read到buffer后在buffer上取一个完整消息段出来就是单个message,也就是zero copy,避免从bufio再到message的拷贝,不确定是否能对性能有所帮助,以及稳定性,因为这样的话pool相关的也需要做相应的修改
  2. 写用bufio+chan struct{}通知flush,因为现在的写是单个消息拼接好了一段buf然后传递给chan去排队写,虽然有batch write的优化,但这里仍然是需要一次拷贝,而如果拼接消息的时候就直接写入到bufio里去,后续的flush就不需要再拷贝了

@smallnest 鸟窝老师,咱们的框架的IO部分比较像,也可以考虑下这两点相关的

lesismal avatar Oct 24 '22 10:10 lesismal

看了测评心血来潮,打算再试着做一波性能优化,大概尝试以下:

  1. 废弃bufio的read,直接read到buffer后在buffer上取一个完整消息段出来就是单个message,也就是zero copy,避免从bufio再到message的拷贝,不确定是否能对性能有所帮助,以及稳定性,因为这样的话pool相关的也需要做相应的修改
  2. 写用bufio+chan struct{}通知flush,因为现在的写是单个消息拼接好了一段buf然后传递给chan去排队写,虽然有batch write的优化,但这里仍然是需要一次拷贝,而如果拼接消息的时候就直接写入到bufio里去,后续的flush就不需要再拷贝了

@smallnest 鸟窝老师,咱们的框架的IO部分比较像,也可以考虑下这两点相关的

想了下,arpc提供的编码中间件是需要以Message为单位的,所以 2 里的zero copy是没什么希望俩,但是bufio+chan flush还是可以再试试,我到时候对比下看看

lesismal avatar Oct 24 '22 10:10 lesismal

今天发现个 frpc 很快,单拼 benchmark 的话,能把我 arpc 拉开一截差距: https://github.com/loopholelabs/frpc-go-benchmarks

但是它这个 rpc 主要就是 rpc,没有那么丰富的功能比如中间件,而且它的协议头只有8字节,单个连接 message id只有两字节的 uint16滚动,即最多 65535 个,在高并发的场景,某个消息如果处理时间较长,这个id滚动一轮了就和把上一轮相同id的 message 混了,不够严谨,所以也没有太大可比性。我前面说的两点优化中的2就是参考它的,但仔细想了下,提升的可能性不大。我继续看看它这个还有没有额外的借鉴之处

其实标准库如果不是用 gob,速度应该也是足够快的,gob的性能太拉跨了

lesismal avatar Oct 24 '22 16:10 lesismal

最近做了个 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

lesismal avatar Aug 10 '23 13:08 lesismal