4. iPerf3 高级参数调优:窗口大小、并行流、缓冲区与时长控制

上一章我们跑通了基础的 iPerf3 测试,拿到了带宽和延迟数据。但说实话,那个结果往往不够「狠」。默认参数下 iPerf3 只开单线程、用系统默认的缓冲区,测出来的吞吐量可能只有链路实际能力的 60%-70%。

我刚开始做网络调优的时候,就吃过这个亏。客户说买了万兆网卡,结果 iPerf3 一测只有 3Gbps,差点把设备商叫来吵架。后来发现,只是窗口大小没调对。嗯,这一章我们就来把这几个「隐藏大招」讲透。

核心观点: iPerf3 的默认参数偏向保守兼容。想要压榨出链路极限,必须手动调整 -w、-P、-t 和缓冲区相关参数。这四个参数分别控制「一次能吞多少」「几个人一起搬」「搬多久」「搬得多细」。

4.1 窗口大小(-w):决定「一次能吃多少」

窗口大小,全称是 TCP 接收窗口(TCP Receive Window)。你可以把它想象成一个水桶——发送方往桶里倒水,接收方从桶里舀水。桶越大,一次能装的水就越多,发送方就不用老等着接收方「倒完再倒」。

默认情况下,Linux 系统的 TCP 窗口是自动调节的,但自动调节往往偏保守。尤其是在高延迟链路(比如跨洲专线、卫星链路)上,默认窗口根本填不满带宽时延积(BDP)。

BDP 计算公式

BDP = 带宽(bps) × RTT(秒) ÷ 8
# 结果单位是字节(Bytes)
# 例如:1Gbps 链路,RTT=20ms
# BDP = 1,000,000,000 × 0.02 ÷ 8 = 2,500,000 Bytes ≈ 2.5MB

也就是说,如果你的链路是 1Gbps、延迟 20ms,窗口至少要设到 2.5MB 才能跑满带宽。默认窗口通常只有 64KB-256KB,差了 10 倍以上。

我的经验: 我个人习惯把 -w 设为 BDP 的 1.5 倍左右。因为 TCP 头部开销、协议栈处理延迟都会吃掉一部分窗口。留点余量,反而更稳。

实战命令示例

# 服务端(不变)
iperf3 -s

# 客户端:设置窗口大小为 4MB,测试 60 秒
iperf3 -c 192.168.1.100 -w 4M -t 60

注意:-w 参数在 Linux 上同时设置发送和接收窗口。在 Windows 上可能只影响发送端,需要两端都设。我曾经在混合 OS 环境里踩过这个坑——Linux 服务端没设 -w,结果客户端设了 8M 也没用。

避坑指南: 我曾经把 -w 设得过大(比如 64MB),结果测试反而变慢了。原因是内核需要分配大块连续内存,导致内存碎片和上下文切换开销。建议从 1M 开始,逐步翻倍,找到拐点。

4.2 并行流(-P):「人多力量大」

单线程 iPerf3 只能用一个 CPU 核心处理网络数据。现代服务器动辄几十个核心,单线程根本跑不满。尤其是多队列网卡(RSS、RPS 技术),每个队列绑定一个核心,单线程只能用一个队列。

-P 参数就是用来开多个并行流的。每个流独立建立 TCP 连接,独立占用一个 CPU 核心和一个网卡队列。

并行流的核心逻辑

  • 适用场景: 多核 CPU、多队列网卡、高带宽链路(≥10Gbps)
  • 不适用场景: 单核虚拟机、低带宽链路(<100Mbps)、延迟敏感测试
  • 典型值: 建议从 -P 4 开始,逐步增加到 CPU 核心数
# 客户端:开 8 个并行流,测试 30 秒
iperf3 -c 192.168.1.100 -P 8 -t 30

你想想看,8 个流同时跑,每个流独立统计。最终结果会汇总显示总带宽和每个流的带宽。如果某个流明显偏低,说明 CPU 核心或网卡队列负载不均。

关键点: -P 不是越大越好。当并行流数超过 CPU 核心数时,反而会因为线程切换导致性能下降。我建议用 nproc 命令查看 CPU 核心数,然后设为核心数或核心数-1。

4.3 缓冲区调优:内核参数与 iPerf3 的配合

除了 -w 参数,Linux 内核还有三个关键缓冲区参数:rmem_default、rmem_max、wmem_default、wmem_max。iPerf3 的 -w 设置不能超过这些内核上限。

查看当前内核缓冲区限制

# 查看接收缓冲区
sysctl net.core.rmem_default
sysctl net.core.rmem_max

# 查看发送缓冲区
sysctl net.core.wmem_default
sysctl net.core.wmem_max

默认值通常是 212992(约 208KB)和 212992。如果你设 -w 4M,但内核上限只有 208KB,那实际生效的还是 208KB。这就是为什么很多人调了 -w 却没效果的原因。

临时修改内核参数(重启失效)

# 将接收缓冲区上限改为 16MB
sysctl -w net.core.rmem_max=16777216
sysctl -w net.core.wmem_max=16777216

# 将默认缓冲区改为 4MB
sysctl -w net.core.rmem_default=4194304
sysctl -w net.core.wmem_default=4194304

永久修改(写入 sysctl.conf)

echo "net.core.rmem_max=16777216" >> /etc/sysctl.conf
echo "net.core.wmem_max=16777216" >> /etc/sysctl.conf
echo "net.core.rmem_default=4194304" >> /etc/sysctl.conf
echo "net.core.wmem_default=4194304" >> /etc/sysctl.conf
sysctl -p
我的习惯: 我一般把 rmem_max 和 wmem_max 设为 16MB,rmem_default 和 wmem_default 设为 4MB。这样 iPerf3 的 -w 可以灵活在 1M-16M 之间调整,不用反复改内核参数。

4.4 时长控制(-t):测多久才够准?

-t 参数控制测试时长,默认是 10 秒。10 秒够吗?说实话,大部分场景不够。

为什么需要更长的测试时间?

  • TCP 慢启动: 前几秒带宽还没爬上去,测出来的结果偏低
  • 突发流量干扰: 短时间测试可能刚好碰上网络空闲或拥塞
  • 散热降频: 长时间高负载下,CPU/网卡可能降频,吞吐量会下降

我记得有一次帮客户验证 40Gbps 链路,默认 10 秒测出来 32Gbps,客户觉得达标了。我说再测 120 秒看看,结果跑到 80 秒时吞吐量掉到了 28Gbps——网卡过热降速了。如果只测 10 秒,根本发现不了这个问题。

时长选择建议

场景 推荐时长 原因
快速验证 10-30 秒 确认连通性和基本带宽
标准性能测试 60-120 秒 覆盖慢启动和稳定期
稳定性测试 300-600 秒 暴露散热降频、内存泄漏等问题
长稳测试 ≥1800 秒(30 分钟) 模拟生产环境持续负载
注意: 长时间测试时,建议配合 -i 1 参数(每秒输出一次结果),这样可以看到吞吐量随时间的变化曲线。如果发现持续下降,基本可以断定有瓶颈。

4.5 综合调优实战:一个完整的例子

假设我们要测试一条 10Gbps、RTT=10ms 的链路。服务器是 16 核 CPU,支持多队列网卡。

第一步:计算 BDP 并设置内核参数

# BDP = 10Gbps × 0.01s ÷ 8 = 12.5MB
# 设置内核缓冲区上限为 32MB(留余量)
sysctl -w net.core.rmem_max=33554432
sysctl -w net.core.wmem_max=33554432
sysctl -w net.core.rmem_default=8388608
sysctl -w net.core.wmem_default=8388608

第二步:服务端启动

iperf3 -s

第三步:客户端执行调优测试

# 窗口设为 BDP 的 1.5 倍 ≈ 18MB
# 并行流设为 16(核心数)
# 时长 120 秒,每秒输出
iperf3 -c 192.168.1.100 -w 18M -P 16 -t 120 -i 1

第四步:分析结果

观察输出中的 SUM 行,看总带宽是否接近 10Gbps。同时看每个流的带宽是否均匀。如果某个流明显偏低,可能是 CPU 亲和性没做好,可以用 taskset 绑定核心。

调优口诀: 先算 BDP,再调内核限;窗口留余量,并行看核心;时长要足够,结果才可信。

4.6 本章知识体系

下面这张图总结了四个核心参数的关系和调优流程。你可以把它当作一个快速检查清单。

iPerf3 高级参数调优知识体系 iPerf3 高级调优 窗口大小 -w 并行流 -P 缓冲区调优 时长控制 -t 控制 TCP 接收窗口 BDP = 带宽 × RTT ÷ 8 建议设为 BDP 的 1.5 倍 多线程并发 TCP 连接 充分利用多核 CPU 建议 ≤ CPU 核心数 内核 rmem/wmem 参数 -w 不能超过内核上限 建议上限设 16MB-32MB 覆盖 TCP 慢启动阶段 暴露散热降频问题 标准测试建议 60-120s 调优流程:计算 BDP → 设置内核上限 → 配置 -w → 配置 -P → 设置 -t 逐步增加参数值,找到性能拐点,避免过度调优

说白了,这四个参数不是孤立的。窗口大小决定了单流能跑多快,并行流决定了能利用多少核心,缓冲区是窗口大小的「天花板」,时长则决定了测试的可信度。把它们组合起来用,才能看到链路的真实极限。

最后一个小建议: 每次调参只改一个变量,记录结果。我习惯用 Excel 或 Markdown 表格记录每次测试的 -w、-P、-t 和最终吞吐量。这样能快速找到最优组合,而不是靠感觉瞎调。