找出 ubuntu 中“合适”的 TCP 窗口大小,以及如何知道如何设置它?

找出 ubuntu 中“合适”的 TCP 窗口大小,以及如何知道如何设置它?

我目前正在构建我的 DIY 路由器的新版本 - 新系统有一对 10 千兆端口。我在 R68S U1 上运行 ubuntu 23.04

最初,在使用 iperf2 进行速度测试时,我知道系统可以处理 10 千兆的线路速度,但我得到的是 5 千兆的速度。华硕的设备指南之一建议使用 iperf 以 800k 进行测试

geek@router-t1:~$ iperf -s -w 800k
------------------------------------------------------------
Server listening on TCP port 5001
TCP window size:  416 KByte (WARNING: requested  781 KByte)
------------------------------------------------------------
[  1] local 10.0.0.1 port 5001 connected with 10.0.0.2 port 52191
[ ID] Interval       Transfer     Bandwidth
[  1] 0.0000-60.0461 sec  35.0 GBytes  5.01 Gbits/sec

有趣的是,这表明我的 TCP 窗口大小较小,这正是华硕所警告的。

这在 Windows 客户端上从未发生过,只有 Linux 客户端才会发生……这很奇怪,但可能是另一个问题

按照建议添加以下几行这里

net.core.wmem_max=4194304
net.core.rmem_max=12582912
net.ipv4.tcp_rmem = 4096 87380 4194304
net.ipv4.tcp_wmem = 4096 87380 4194304

导致基准值翻倍

geek@router-t1:~$ iperf -s -w 800k -B 10.0.0.1
------------------------------------------------------------
Server listening on TCP port 5001
TCP window size: 1.53 MByte (WARNING: requested  781 KByte)
------------------------------------------------------------
[  1] local 10.0.0.1 port 5001 connected with 10.0.0.2 port 57480
[ ID] Interval       Transfer     Bandwidth
[  1] 0.0000-60.0443 sec  69.2 GBytes  9.90 Gbits/sec

我理解这会调整套接字接收缓冲区和新创建套接字的缓冲区大小 - IBM 在这里对此有一个很好的解释他们在这里做

我如何计算出给定系统的适当尺寸,以及为什么这会产生如此显著的效果?

答案1

为了实现最大吞吐量,TCP 窗口大小必须足够大,以允许发送方“保持管道满载”,这意味着它需要能够以链路可以承受的速度继续发送全尺寸段,并且持续足够长的时间才能收到第一个数据包的确认。该确认时间将是该网络路径的往返时间 (RTT),这是测量值ping(8),但请注意,在空闲网络上通过 ping 测量的 RTT 可能低于 TCP 发送方在保持 10Gbps 链路满载时看到的 RTT。

我们通常将此计算称为“带宽 x 延迟乘积”(BDP)。因此,将带宽(单位为比特/秒)乘以 RTT(单位为秒)。这样可以将秒数相消,从而得出在任何给定时间可能需要“在飞行中”(“在网络中”、“在管道中”)的位数,以保持管道满载。

因此,使用我通常在以太网 LAN 上看到的 10Gbps 和 0.3ms 典型有线以太网 LAN 空闲 ping 时间,那将是 10,000,000,000 位/秒 x 0.0003 秒 = 3,000,000 位 = 大约 366 KibiBytes。

因此,初步估计,您原来的 416KiByte TCP 窗口应该可以实现全速性能。这表明,我估计的 0.3ms RTT 对于 10Gbps 链路上 TCP 的实际速度来说太低了。

如果我将 RTT 估计值修改为 1ms,我会得到 1.2MiBytes 的 BDP,这更符合您在成功示例中调整 sysctl 以提供更多扩展空间后 Linux TCP 堆栈将窗口自动缩放到的 1.53MiByte 大小。

对于 LAN 上的个人计算机来说,为每个 TCP 连接分配几兆字节的 RAM 作为接收窗口是没问题的,但对于必须处理数百或数千个同时 TCP 连接的繁忙服务器来说,这可能是一个问题。RAM 很快就会用完。这也是大多数现代 TCP 实现都内置并默认启用窗口自动缩放算法,但由 sysctl 限制的原因之一。

相关内容