【转载】从零理解 TCP 拥塞控制:为什么 BBR 比 CUBIC 快

2026-08-12   网络转载TCP
📋 转载说明:本文转载自知乎专栏,作者:网络工程师小李, 原文已注明 CC BY-SA 4.0 协议,允许转载并注明来源。 原文链接:知乎专栏
网络拥塞控制示意:发送速率与网络容量的关系

网络拥塞控制示意:发送速率与网络容量的关系

一、TCP 拥塞控制的问题背景

互联网上的数据传输依靠 TCP,而 TCP 有一个核心难题:发送方不知道网络当前的承载能力,它只能通过"感知"来估计——发快了会丢包,发慢了浪费带宽。

传统的拥塞控制算法(Reno、CUBIC)都基于一个假设:丢包 = 网络拥塞。逻辑是这样的:

  1. 慢启动:指数级增加发送速率
  2. 拥塞避免:线性增加
  3. 检测到丢包:速率砍半,重新探测

这个逻辑在互联网早期很有效。但现代网络有一个变化打破了它——缓冲区膨胀(Bufferbloat)。

二、CUBIC:基于丢包的拥塞控制

CUBIC 是 Linux 内核 2.6.19 以后的默认算法,也是目前大多数服务器在用的算法。它用一个三次函数来控制窗口增长,在丢包后快速恢复,适合高带宽长距离链路。

CUBIC 的拥塞窗口变化曲线

CUBIC 的拥塞窗口变化曲线

CUBIC 的问题在于:现代路由器和交换机为了减少丢包,设置了很大的缓冲区。发送方可以一直塞数据进去,直到缓冲区满了才丢包——这时缓冲区里已经积累了大量数据,产生了严重的延迟。这就是"缓冲区膨胀"。

典型场景:你家的 4G 下行跑满的同时,打游戏延迟从 20ms 飙到 300ms——带宽很高,但延迟很差,就是因为缓冲区被塞满了。

三、BBR 的核心思想

Google 在 2016 年提出 BBR(Bottleneck Bandwidth and Round-trip propagation time),它彻底换了一个思路:不以丢包作为拥塞信号,而是主动测量网络的真实带宽和最小 RTT,把发送速率控制在"刚好不填满缓冲区"的水平。

BBR 要估算两个量:

理想的发送速率 = BtlBw,理想的在途数据量(inflight)= BtlBw × RTprop(即 BDP,带宽时延积)。

BBR 与 CUBIC 的吞吐量和延迟对比测试结果

BBR 与 CUBIC 的吞吐量和延迟对比测试结果

四、BBR 的四个阶段

阶段目的pacing_gain
STARTUP快速探测带宽上限,类似慢启动2/ln2 ≈ 2.88
DRAIN排空 STARTUP 多填入缓冲区的数据ln2/2 ≈ 0.35
PROBE_BW稳态运行,周期性探测带宽变化在 1.25 和 0.75 之间循环
PROBE_RTT定期降速以测量真实 RTprop—(cwnd 降到 4)

其中 PROBE_BW 是最重要的稳态阶段。BBR 每 8 个 RTT 循环一次:用 1 个 RTT 以 1.25× 速率探测更多带宽,用 1 个 RTT 以 0.75× 速率排队,剩余 6 个 RTT 以 1.0× 稳定运行。这个设计让 BBR 能持续感知带宽变化,同时不会长期过度占用缓冲区。

五、BBR v2 和 v3 改进了什么

BBR v1 有一个被批评的问题:在与 CUBIC 共存时,BBR 会占用更多带宽,对 CUBIC 流不公平。原因在于 CUBIC 会因丢包退缩,而 BBR 不在意丢包,继续维持发送速率。

BBR v2(2019)和 v3(2023)引入了对丢包信号的适度响应,同时保留了基于 BDP 的带宽估计核心,改善了公平性。Google 在其全球骨干网(B4)上大规模部署 BBRv2/v3 后,吞吐量提升显著,延迟更稳定。

TCP 拥塞控制原理与 BBR 详解视频讲解(B站)

六、实际应用建议


原文作者:网络工程师小李 · 发布于知乎专栏 · 转载已获授权(CC BY-SA 4.0)· 本站仅做排版调整,未修改原文内容