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 验证。一切按实际链路算,别照搬玄学配置。