『调错』大半夜调试TCP延迟问题
背景
公司有个项目,需要一个高可用缓存服务。
之前通讯技术选型时,测试过 UDP TCP HTTP QUIC gRPC 性能。
初步结论:
1、UDP 很快,CPU 很低,但无法超过 64K (大于12K 甚至都开始内网丢包)
2、HTTP 传统的 WebApi (中规中矩的技术选型,延迟都还好,但真想完善还得每次增加 WebApi 安全验证 —— 就开始损失性能了)
3、传说中的 Quic,说是用UDP实现了一套类似 TCP 的重发机制(实测 CPU 增加,吞吐降低 —— 真就和本机TCP一样了)
4、本来自己心目中最想用的是 TCP(有一套成熟的TCP库,实战从未失望),只需建立连接时只需一次安全验证(目前很多数据库、Redis、MQTT、RabbtMQ 底层都是TCP,也都是连接时安全验证)—— 但不知道为啥,局域网跨机部署 一来一回一次交互 延迟达到到 100ms(经验中:同步的 一来一回 TCP 本机可以达到 5000/s ~ 7000/s)。
TCP让我很气馁
印象中的 TCP:
- 单核同步速度 5000/s ~ 7000/s
- 四核异步速度 可以把CPU跑满,30000/s 都只是小意思
但这次跨机部署,每次交互 100ms 延迟(折合 10/s 的速度 —— 这还玩毛线)
虽然多核异步,依然能把带宽跑满,交互也能达到 30000/s 吞吐量 —— 但每次交互的延迟 100ms 就很不合适。
难道是我之前的项目,都只在乎吞吐量,却没有关注延迟的缘故 ?
TCP 减少延迟调优
优化前的现状
本机交互 0ms,吞吐量 7000/s
虚拟机交互 85ms,吞吐量 20/s
虚拟机ping延迟 1ms —— ping 一来一回也就 1ms, 没理由 TCP 一来一回 85ms 啊
使用异步代码优化后(没啥用)
本机交互 0ms,吞吐量 7000/s
虚拟机交互 85ms,吞吐量 20/s
会不会是 Linux 的问题?换成 Win10 和 Win10 交互还是鸟样
找到关键优化代码
虚拟机交互 0ms
最终吞吐量 800/s
至此,执念已消,总结:
最终优化后的代码,依然选用回调异步
真正其决定性作用的参数是这个 NoDelay
TCP的 吞吐量 和 延迟 区别
- 延迟,比如一个单车道,路面坑坑洼洼 一辆车一来一回 100秒,路面平整 一辆车一来一回 10秒 (这就是延迟)
- 吞吐量,比如一个 100车道,虽然路面坑坑洼洼,延迟虽高,但吞吐量依然可以很大
- 降低了延迟后,原本100个车道的吞吐量,只需要 10个车道即可
- 本文只记录了如何降低延迟,没有测试多并发时的吞吐量 —— 不用测,30000/s + 一定是了
小INK
2023-03-30 01:17
晚安,各位。