最近我用 iperf3(Centos 7.5 内核 3.10 上的 3.1.7,然后我尝试了从源代码编译的 3.7+)做了一些网络测试,但我对结果感到困惑。
我使用的语法是iperf3 -c -b 500M
,无论是 TCP 还是 UDP 测试。我的理解是,默认情况下,iperf3 会进行某种内部调整以保持所需的速率。
我读到,在较新版本的 iperf3 中,控制起搏机制的计时器具有相当好的分辨率(1 毫秒),因此流量不应该非常突发。
问题是,对于 UDP 测试,我遇到了数据包丢失(1%-2%),而 TCP 测试达到了所需的最大带宽并且没有报告重传。
我对步调的具体工作原理没有很好的了解,但我倾向于认为,如果 TCP/UDP 的情况相似并且问题出在网络上,我应该期待 UDP/TCP 的结果一致(因此,在 TCP 的情况下需要重新传输)。
有人遇到过类似的结果吗?如果有,这种差异的原因是什么?
答案1
数据包可能会在网络的不同点丢失。我看不出网络硬件在 UDP 方面存在更多问题的任何理由。
我可以想象,接收系统将 UDP 数据包及时发送到接收应用程序会更加困难。我不太了解细节,但传入数据包的缓冲区是有限的。
使用 TCP,内核可能更容易将传入的数据包聚合成更大的数据块,然后将其提供给应用程序。如果应用程序以 UDP 模式发送少量数据,以便每个数据单元都适合单个 UDP 数据包,那么接收内核就无法聚合任何数据。由于 UDP 是无状态的,因此必须单独读取每个数据包。
我猜想,在 UDP 模式下,内核和应用程序之间的传输次数较多可能是瓶颈,接收内核会丢弃这些数据包,因为应用程序无法及时读取它们。请查看接收系统Recv-Q
的输出中的列。ss -un
您还可以tcpdump -p
在开始基准测试之前,先在两个系统上对那些 UDP 数据包进行过滤,然后比较看到的数据包数量。如果数字相同,则说明接收内核已丢弃数据包。如果应用程序发送的数据块无法装入单个 UDP 数据包,则您可能必须在两个接口上禁用 GSO,才能看到正确的 UDP 数据包数量。由于额外的 CPU 负载,我预计tcpdump
运行时数据包丢失会增加。
您还可以查看 的输出ip -s link
:RX: overrun
如果该数字大于零,则数据包被接收硬件丢弃,因为内核没有及时读取它们。这些数据包不会出现在 中tcpdump
。
答案2
TCP 协议中集成了拥塞避免功能。拥塞窗口、慢启动策略。有时还会有明确的拥塞通知。
UDP 则不然。尽管 iperf 在应用程序级别进行了节流,但它仍会发送恒定速率(此处为 500M),而不管链接速度如何,也不管线路上还有其他什么。如果带宽已达到饱和状态,那么 2% 的损失相对较小。
答案3
啊,数据包丢失的接口问题会重置 TCP 窗口,从而减少明显的带宽。UDP 将继续运行,导致 UDP 的结果比 TCP 更好。
我们在数据中心发现了这个问题,那里有一个故障的 SFP