我有一台带有千兆上行链路的服务器,使用iperf3
100 个并行连接进行测试,我至少能获得 600 MBit/s,具体取决于其他服务器(我尝试了一些公共测试服务器)。但是当我iperf3
使用一个连接运行时,我得到10-15 MBit/s
,使用两个连接时20-30 MBit/s
,依此类推。
我没有非常复杂的 iptables 规则,也不知道为什么它这么慢。单个 tcp 连接的限制因素是什么,以至于它们比可能的带宽慢 10 倍?
答案1
我终于找到了问题的原因。
我有一些 flask webapp,它使用 redis 将事件流式传输给用户。当用户断开连接时,该应用程序保持 redis pubsub 连接处于活动状态,不再读取数据。
这会导致较长的Send-Q
/ Recv-Q
,显然会导致 tcp 堆栈变慢并产生内核警告:“TCP:内存不足——考虑调整 tcp_mem“。
- 短期修复:终止具有长数据包队列的进程。
- 长期解决方案:修复行为不当的程序。
答案2
单个 TCP 会话受每个会话窗口大小的限制,该窗口表示在任意给定时间内两个端点之间可以“传输”的最大字节数。因此,如果您的链接延迟较高,则可能会达到每个会话的限制,即窗口大小/RTT。
解决此问题的唯一方法(因为您通常无法对 RTT 做很多事情)是使用更多会话,或者使用窗口缩放显著增加窗口大小。我不知道 iPerf 的设置与此相关,或者您是否可能在端点之间有防火墙或其他过滤器,即使 iPerf 和您的服务器都支持缩放,也会阻止缩放。