TCP 缓冲区与拥塞控制优化指南

详解 TCP 发送/接收缓冲区(tcp_rmem/tcp_wmem)与 BBR 拥塞控制算法优化,覆盖默认值查询、持久化配置、内存规划、BBR 启用与回退机制,含 Ubuntu 22.04 实测回显。

Linux性能优化与调优TCP优化网络优化2026/09/29

TCP 缓冲区与拥塞控制优化指南

目标:优化 Linux TCP 收发缓冲区大小并引入 BBR 拥塞控制算法,提升高带宽长肥网络(长 RTT、大带宽)的吞吐表现。核心参数 net.ipv4.tcp_rmem、net.ipv4.tcp_wmem 与拥塞控制算法 tcp_congestion_control。本文命令在 Ubuntu 22.04(内核 6.8.0-generic)实测。

环境信息

  • 操作系统:Ubuntu 22.04.5 LTS;内核:6.8.0-138-generic
  • 实测默认值:
    • net.ipv4.tcp_rmem = 4096 131072 6291456(min / default / max,单位字节)
    • net.ipv4.tcp_wmem = 4096 16384 4194304
    • net.ipv4.tcp_congestion_control = cubic

前置条件

  • root 权限。
  • BBR 需要内核 ≥ 4.9 且编译进 tcp_bbr 模块(Ubuntu 22.04 已内置)。

TCP 缓冲区原理

每个 TCP socket 有独立的接收(read)与发送(write)缓冲区,取值由三个整数限定:

tcp_rmem = 最小堆内存  默认值  最大堆内存   (字节)
tcp_wmem = 最小 默认 最大
  • 最小:socket 建立时的初始分配。
  • 默认:自动拥塞窗口调节的基准。
  • 最大:接收/发送窗口所能达到的上限,决定单连接可缓存的数据量上限。

💡 说明:缓冲越大,单连接可吸收的高带宽突发越多,但每个连接占用的内存也越大。应在吞吐与内存/并发之间权衡。

参数查看与临时修改

# 查看当前值
sysctl net.ipv4.tcp_rmem net.ipv4.tcp_wmem net.ipv4.tcp_congestion_control
# net.ipv4.tcp_rmem = 4096 131072 6291456
# net.ipv4.tcp_wmem = 4096 16384 4194304
# net.ipv4.tcp_congestion_control = cubic

# 临时调整接收缓冲区(3 个值:最小 默认 最大)
sysctl -w "net.ipv4.tcp_rmem=4096 65536 16777216"
# net.ipv4.tcp_rmem = 4096 65536 16777216

# 临时调整发送缓冲区
sysctl -w "net.ipv4.tcp_wmem=4096 65536 16777216"

# 启用 BBR 拥塞控制
sysctl -w net.ipv4.tcp_congestion_control=bbr
# net.ipv4.tcp_congestion_control = bbr

⚠️ 注意:直接改 tcp_rmem 只影响新建立的连接;已建立的连接需用 ss/setsockopt 或重连才生效。

生产持久化配置

写入 /etc/sysctl.d/99-tcp-tune.conf:

# 99-tcp-tune.conf —— TCP 收发包优化
# 接收缓冲:min 4k / 默认 64k / 最大 16MB
net.ipv4.tcp_rmem = 4096 65536 16777216
# 发送缓冲:min 4k / 默认 64k / 最大 16MB
net.ipv4.tcp_wmem = 4096 65536 16777216
# 统计要不要自动扩大窗口(TCP autotuning),建议开启
net.ipv4.tcp_window_scaling = 1
# 拥塞控制算法(可用 alternate:cubic bbr)
net.ipv4.tcp_congestion_control = bbr
# TCP 时间戳,配合窗口扩大使用
net.ipv4.tcp_timestamps = 1

加载并验证:

sysctl -p /etc/sysctl.d/99-tcp-tune.conf
sysctl net.ipv4.tcp_rmem net.ipv4.tcp_wmem net.ipv4.tcp_congestion_control

BBR 拥塞控制详解

BBR(Bottleneck Bandwidth and Round-trip propagation time)由 Google 提出,不依赖丢包反馈,而是基于瓶颈带宽与最小 RTT 建立模型,在高带宽高 RTT 链路显著优于传统的丢包驱动算法(cubic/reno)。

启用与验证:

# 确认可用(Ubuntu 22.04 已内置)
sysctl net.ipv4.tcp_available_congestion_control
# tcp_available_congestion_control = bbr cubic reno

# 生效(临时)
sysctl -w net.ipv4.tcp_congestion_control=bbr

# 持久化
echo "net.ipv4.tcp_congestion_control=bbr" > /etc/sysctl.d/99-tcp-tune.conf
sysctl -p /etc/sysctl.d/99-tcp-tune.conf

# 验证
sysctl net.ipv4.tcp_congestion_control
# net.ipv4.tcp_congestion_control = bbr

⚠️ 注意:若 tcp_available_congestion_control 没有 bbr,说明内核未启用 BBR,需 modprobe tcp_bbr 并确保内核配置 CONFIG_TCP_CONG_BBR=y。对延迟极敏感的小包应用,BBR 提升未必显著,需 A/B 压测验证。

常见问题

Q:缓冲调大后内存暴涨? A:缓冲是"按需增长",常见并发会按默认值不足分配;只有连接真正吞吐大时窗口才扩到 max。但若 net.core.rmem_max/wmem_max 也调大,需监控内存。

Q:BBR 比 cubic 一定快吗? A:在公网跨区域、移动网络等丢包率高、带宽高的场景通常更优;在近乎无丢包的内网,两者差异小,建议用压测工具(iperf3)对比。

Q:改了拥塞控制没生效? A:确认已写入并 sysctl -p,且 tcp_available_congestion_control 含该算法。

卸载方式

删除 /etc/sysctl.d/99-tcp-tune.conf 并 sysctl --system;或恢复默认 net.ipv4.tcp_congestion_control=cubic。

参考链接

  • 内核文档必读:Documentation/networking/ip-sysctl.txt
  • BBR 论文:https://datatracker.ietf.org/doc/html/draft-cardwell-iccrg-bbr-congestion-control