读完 BBR 论文,我重做了几条 TCP 调优
BBR 不是"换个拥塞控制算法"那么简单。读懂论文之后,我对若干条生产环境的 TCP 调优做了反思与重做。一份带数字的笔记。
Google 在 2016 年发的 BBR 论文,我读过三遍。第一遍没读懂,第二遍读懂了但不会用,第三遍才真正把它落到生产。这次重读后,我对若干条 TCP 调优做了反思与重做。整理成笔记。
BBR 与 CUBIC 的根本区别
CUBIC 是"基于丢包"的拥塞控制——发到开始丢包,就认为到了瓶颈,回退窗口。BBR 是"基于带宽与 RTT"——主动测量瓶颈带宽与最小 RTT,把窗口设为 BtlBw × RTT。
这两种思路在以下场景差别巨大:
- 浅缓冲链路:CUBIC 没机会丢包就一直发,BBR 能精确测量带宽。
- 深缓冲链路:CUBIC 把 buffer 填满造成 bufferbloat,BBR 不依赖丢包,避免填充 buffer。
- 无线网络:随机丢包被 CUBIC 当拥塞,BBR 不受影响。
BBR 的核心洞察:丢包 ≠ 拥塞。把"丢包"作为拥塞信号是 1980 年代的妥协,今天该换思路了。
从论文里学到的三件事
BBR 的状态机有四态:StartUp、Drain、ProbeBW、ProbeRTT。理解它要抓住三个关键点:
- 用 BtlBw × RTT 代替 cwnd:窗口不再是"丢出来的",是"算出来的"。
- 周期性 probe:每 10 秒一个周期,主动加窗看是否能拿到更高带宽。
- ProbeRTT 是必要的恶:每 10 秒把窗口压到 4 包,测真实最小 RTT。这会带来周期性延迟抖动。
调优反思 1:默认启用 BBR 的代价
我以前在生产环境默认把内核 net.ipv4.tcp_congestion_control 设成 bbr。读完论文后改成"分场景":
- 跨机房内网:保持 cubic。内网浅缓冲 + 低 RTT,BBR 优势不明显。
- 跨地域公网:启用 bbr。高 RTT + bufferbloat,BBR 收益大。
- 客户端到 CDN:启用 bbr。客户端网络多样,BBR 更鲁棒。
全量切 BBR 后,我们发现内网某些短连接的延迟反而升高——ProbeRTT 周期性把窗口压到 4,对短连接不友好。改回 cubic 后正常。
调优反思 2:BBR 与 ECN 的冲突
我们曾同时启用 BBR + ECN(Explicit Congestion Notification)。结果某些链路上吞吐反而下降。读完论文才明白:BBR 不依赖丢包做拥塞信号,但 ECN 仍是"丢包类"信号。两者叠加时,BBR 会被 ECN 错误地"惩罚"。后来我们改成"BBR 不开 ECN"。
调优反思 3:BBR v2 / BBRv3 的进步
BBR v1 在某些场景有 fairness 问题——多个 BBR 流共享瓶颈时分配不均,且对 CUBIC 流有侵略性。BBRv2/v3 改进:
- 支持 ECN 反馈。
- 降低对 CUBIC 流的侵略性。
- ProbeRTT 不再那么激进。
- 更友好的多流公平性。
我们的生产内核升到 5.18+ 后切到 BBRv2,fairness 问题显著缓解。但 BBRv2 仍在演进,参数比 v1 复杂得多。
几个实测数据
| 场景 | CUBIC | BBR v1 | BBR v2 |
|---|---|---|---|
| 跨机房内网吞吐 | 9.2 Gbps | 9.0 Gbps | 9.1 Gbps |
| 跨地域公网吞吐 | 410 Mbps | 620 Mbps | 610 Mbps |
| 跨地域 RTT 抖动 P99 | 180ms | 95ms | 92ms |
| 弱网客户端下载 | 1.2 Mbps | 2.8 Mbps | 2.7 Mbps |
关键观察:内网场景 BBR 收益微弱甚至略负;公网与弱网场景 BBR 收益巨大。
启用 BBR 的正确姿势
# 检查内核支持
modprobe tcp_bbr
sysctl net.ipv4.tcp_available_congestion_control
# 启用
echo "net.core.default_qdisc = fq" >> /etc/sysctl.conf
echo "net.ipv4.tcp_congestion_control = bbr" >> /etc/sysctl.conf
sysctl -p
关键点:必须配合 fq(fair queue)队列。BBR 假设底层队列是 fq,否则 pacing 不准确。
BBR 不是银弹
读完论文最大的收获是"知道 BBR 的边界":
- 浅缓冲 + 低 RTT 链路:CUBIC 与 BBR 差距小。
- 长肥管道(高带宽 × 高 RTT):BBR 优势大。
- 极小流量场景:BBR 的 StartUp 阶段可能过激进。
- 极重 ProbeRTT 影响短连接:BBR v1 的 ProbeRTT 对 100ms 内的短连接不友好。
给团队的简短建议
- 分场景启用 BBR:公网/弱网启用,内网保持 cubic。
- 必须配 fq 队列。
- 内核 5.18+ 优先用 BBRv2。
- 启用后看吞吐 + RTT 抖动双指标,不能只看吞吐。
BBR 是 TCP 拥塞控制近 30 年最大的进步。但它不是银弹,理解它的状态机与边界,才能用对地方。读论文这件事,看似慢,其实是工程师最快的捷径。