第三章 TCP 带宽测试:窗口大小对带宽的影响与缓冲区调优
大家好,我是老张。今天咱们聊聊 TCP 带宽测试里一个特别关键、也特别容易踩坑的话题——TCP 窗口大小。
说实话,我见过太多人拿着 iperf 跑个测试,看到带宽上不去就怪网络。其实很多时候,问题出在 TCP 窗口上。你想想看,TCP 就像一个水管,窗口大小就是水管的直径。直径太小,水流自然上不去。
3.1 TCP 窗口的基本概念
TCP 窗口,全称是 TCP 接收窗口(Receive Window,简称 RWIN)。它告诉发送方:「嘿,你最多能发这么多数据,不用等我确认。」
说白了,这就是一个流量控制机制。接收方告诉发送方自己还有多少缓冲区可用,发送方就按这个量来发。
核心公式:
带宽延迟积(BDP)= 带宽 × 往返时延(RTT)
理想窗口大小 ≥ BDP
举个例子。假设你的链路是 1Gbps,RTT 是 10ms。那么 BDP 就是:
BDP = 1,000,000,000 bps × 0.01 s = 10,000,000 bits = 1.25 MB
这意味着,你的 TCP 窗口至少得 1.25MB,才能把带宽跑满。如果窗口只有 64KB,那实际吞吐量最多也就 51.2Mbps。嗯,差了将近 20 倍。
3.2 窗口大小对带宽的影响
我在项目中遇到过一件事。有个客户说他们的专线带宽是 100Mbps,但实际传输文件只有 20Mbps。我上去一看,RTT 是 80ms,窗口大小还是默认的 64KB。
算一下:
最大吞吐量 = 窗口大小 / RTT = 64KB / 0.08s = 800KB/s ≈ 6.4Mbps
你看,连 20Mbps 都不到。这就是窗口太小导致的瓶颈。
为什么会这样?因为发送方发完一个窗口的数据后,必须等接收方确认才能继续发。窗口越小,等待确认的次数就越多,效率自然就低了。
| 窗口大小 | RTT = 10ms | RTT = 50ms | RTT = 100ms |
|---|---|---|---|
| 64KB | 51.2 Mbps | 10.2 Mbps | 5.1 Mbps |
| 256KB | 204.8 Mbps | 41.0 Mbps | 20.5 Mbps |
| 1MB | 819.2 Mbps | 163.8 Mbps | 81.9 Mbps |
| 4MB | 3.2 Gbps | 655.4 Mbps | 327.7 Mbps |
从这张表能看出来,RTT 越大,窗口大小的影响就越明显。长肥网络(Long Fat Network)里,窗口大小就是命根子。
3.3 如何调整 TCP 缓冲区
调整 TCP 缓冲区,说白了就是改几个内核参数。我个人习惯在 Linux 系统上操作,因为灵活、可控。
3.3.1 Linux 系统调优
Linux 的 TCP 缓冲区有三个关键参数:
net.core.rmem_default:接收缓冲区默认大小net.core.wmem_default:发送缓冲区默认大小net.core.rmem_max和net.core.wmem_max:最大缓冲区大小
还有一组是 TCP 专用的:
net.ipv4.tcp_rmem:接收缓冲区(最小值、默认值、最大值)net.ipv4.tcp_wmem:发送缓冲区(最小值、默认值、最大值)
我建议这样设置:
# 调整系统级缓冲区
sysctl -w net.core.rmem_max=16777216
sysctl -w net.core.wmem_max=16777216
sysctl -w net.core.rmem_default=262144
sysctl -w net.core.wmem_default=262144
# 调整 TCP 缓冲区
sysctl -w net.ipv4.tcp_rmem="4096 87380 16777216"
sysctl -w net.ipv4.tcp_wmem="4096 65536 16777216"
# 启用窗口缩放
sysctl -w net.ipv4.tcp_window_scaling=1
小提示:窗口缩放(Window Scaling)必须开启。否则窗口最大只能到 64KB,调再大也没用。我见过有人改了缓冲区大小但忘了开缩放,折腾了半天才发现。
3.3.2 Windows 系统调优
Windows 下调整稍微麻烦点,得改注册表:
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters
# 设置 TCP 窗口大小
TcpWindowSize = DWORD (十进制,单位字节)
# 例如 16777216 表示 16MB
# 启用窗口缩放
Tcp1323Opts = DWORD (3 表示启用所有选项)
改完记得重启。嗯,Windows 嘛,你懂的。
3.4 实战:用 iperf 测试窗口影响
光说不练假把式。咱们用 iperf 实际测一下。
先启动服务端:
iperf3 -s -p 5201
客户端测试,默认窗口:
iperf3 -c 192.168.1.100 -p 5201 -t 30
然后手动指定窗口大小:
iperf3 -c 192.168.1.100 -p 5201 -t 30 -w 1M
对比两次结果。我敢打赌,如果 RTT 比较大,第二次的带宽会明显提升。
注意:iperf 的 -w 参数设置的是 TCP 窗口大小,但实际生效的是 min(发送端窗口, 接收端窗口)。所以两端都要调大才行。我曾经在测试时只调了客户端,服务端没动,结果带宽还是上不去。排查了半天才发现是服务端限制了窗口。
3.5 知识体系图
下面这张图总结了 TCP 窗口与带宽的关系:
3.6 避坑指南
最后,分享几个我踩过的坑:
- 别盲目调大窗口:窗口太大,丢包重传的成本也高。我建议从 BDP 的 1.5 倍开始试。
- 注意中间设备:有些防火墙、负载均衡器会改写 TCP 窗口。我曾经遇到过,调了半天客户端和服务端,结果中间设备把窗口给限制了。
- 窗口缩放不是万能的:有些老设备不支持窗口缩放,得确认两端都支持。
- 实测为准:理论算得再好,不如实际跑一次 iperf。我习惯在调优前后各测三次,取平均值对比。
一句话总结:TCP 窗口大小决定了你能用多少带宽。调优的核心就是让窗口 ≥ 带宽 × RTT。别偷懒,算清楚再动手。
好了,这一章就到这里。记住,调窗口是基本功,但也是很多性能问题的根源。下次遇到带宽上不去,先看看窗口大小对不对。
想要更多资料,联系可可