TCP 内核参数调优:高延迟链路提速

高延迟大带宽链路慢,多半是 TCP 缓冲太小卡住了吞吐;按 BDP 估算放大缓冲、开 window scaling、配合 BBR,就能跑满带宽。

为什么高延迟链路会"跑不满"

TCP 用滑动窗口控制在途(已发送未确认)数据量。一条链路一次最多能"塞"多少字节,取决于带宽时延积(BDP):

BDP(字节) = 带宽(字节/秒) × RTT(秒)

比如一条 200 Mbps、RTT 150ms 的跨洋线路:

200 Mbps ≈ 25 MB/s
BDP = 25,000,000 × 0.15 ≈ 3.75 MB

如果 TCP 缓冲上限只有默认的几百 KB,窗口撑不到 BDP,链路就"空着一大半",无论带宽多大都跑不快。

需要调的参数

先确认 window scaling 已开(高 BDP 的前提,现代内核默认开):

sysctl net.ipv4.tcp_window_scaling   # 应为 1

在 /etc/sysctl.d/99-tcp-tuning.conf 写入(数值按你的 BDP 估算,下面以约 8 MB 上限为例):

# 三段值:最小 默认 最大(字节)
net.ipv4.tcp_rmem = 4096 131072 8388608
net.ipv4.tcp_wmem = 4096 16384 8388608
# socket 缓冲绝对上限
net.core.rmem_max = 8388608
net.core.wmem_max = 8388608
# 保持接收缓冲自动扩缩
net.ipv4.tcp_moderate_rcvbuf = 1

要点:tcprmem/tcpwmem 的第三个值是自动调优的上限,不是一上来就占满。把上限抬到略高于 BDP,内核会按需增长即可;rmemmax/wmemmax 必须 ≥ 上面的最大值,否则被截断。

配合 BBR

把拥塞控制算法换成 BBR,在高丢包/高延迟链路上通常明显优于默认的 cubic:

net.core.default_qdisc = fq
net.ipv4.tcp_congestion_control = bbr

BBR 需要内核 4.9+(Ubuntu 20.04 / Debian 11 及以上都满足)。

生效与验证

sudo sysctl --system                       # 或 sysctl -p 指定文件
sysctl net.ipv4.tcp_congestion_control     # 确认 bbr
sysctl net.core.rmem_max                   # 确认新值

再用 iperf3 对拉一遍,对比调优前后的吞吐——用数据验证,别信"改了就快"。

边界提醒

  • 别照抄网上的玄学大数值。缓冲是每连接上限,高并发服务器上 × 连接数 可能吃光内存甚至触发 OOM。按实际 BDP 留 12 倍余量就够。
  • 只对高 BDP(高延迟或大带宽)路径有效;本地/低延迟链路、CPU 或磁盘瓶颈、应用层限速都调不动。
  • 两端都要有余量:下载受接收端 rmem 制约,上传受发送端 wmem 制约。
  • 逐项改、逐项测,别一次堆十几个参数,出问题难定位。

小结

高延迟链路提速的核心是让 TCP 窗口撑满 BDP:估算 BDP → 抬高 tcprmem/tcpwmem 上限与 rmemmax/wmemmax → 确认 window scaling → 配合 BBR → sysctl --system 生效 → 用 iperf3 验证。一切按实际链路算,别照搬玄学配置。