TCP 拥塞控制算法选择与配置:CUBIC、BBR、Vegas
拥塞控制算法是 TCP 传输性能的“隐形之手”。选对了,万兆链路跑满;选错了,丢包一多就掉速。我见过不少团队花大价钱升级带宽,结果瓶颈却在拥塞控制算法上。
这章咱们把 Linux 上最主流的三种算法——CUBIC、BBR、Vegas——的原理和适用场景掰开揉碎讲清楚。我会结合自己的踩坑经历,帮你快速判断该用哪一种。
CUBIC:Linux 默认的“老大哥”
CUBIC 是 Linux 内核的默认拥塞控制算法(从 2.6.19 起)。它的核心思想是:用三次函数来描述拥塞窗口的恢复过程。说白了,窗口增长不是单纯的“加法增”,而是先快后慢再快,类似一个“S”形曲线。
关键数学特性:窗口增长速率只与丢包发生的时间距离有关,与 RTT 无关。这意味着 CUBIC 特别适合“长肥管道”——高带宽、大延迟的网络。
我在一次跨国专线项目中遇到过:国内到美国洛杉矶的链路,RTT 约 180ms,带宽 1Gbps。默认 CUBIC 单流只能跑 200Mbps 左右,换成 BBR 后直接飙到 900Mbps。当然这不能怪 CUBIC——它本来就为“公平性”和“RTT 独立性”设计,在共享瓶颈链路上表现稳定。
CUBIC 的适用场景
- 大延迟 + 高带宽(如卫星链路、跨洋 VPN)
- 多流公平共存(数据中心内部,几百个 TCP 流竞争)
- 丢包率较低的环境(有线网络,丢包 < 1%)
- 兼容性要求高(老系统默认自带,无需额外安装)
注意:丢包率一旦超过 2%,CUBIC 的窗口会剧烈回退,吞吐量断崖式下降。我曾在一个 WiFi 环境下测试,丢包 5% 时 CUBIC 吞吐只剩下 CUBIC 理论峰值的 10%。
BBR:Google 的“算命先生”
BBR(Bottleneck Bandwidth and Round-trip propagation time)不依赖丢包,而是通过实时探测瓶颈带宽和最小 RTT 来建模链路。它像一个算命先生,不断“估算”管道容量,然后让发送速率刚好卡在极限边缘。最大的区别是:BBR 不把丢包当成拥塞信号,所以抗丢包能力强。
我记得 2018 年刚接触 BBR 时,在一个高丢包的移动网络场景中测试:4G 网络下随机丢包 3%,CUBIC 几乎无法完成视频通话,BBR 却稳定输出 8Mbps。那一刻我意识到,算法选对,网络体验天差地别。
BBR 的适用场景
- 高丢包网络(无线、卫星、移动)
- 动态带宽变化(4G/5G、WiFi 漫游)
- 长距跨洋链路(RTT 大,但带宽大)
- 实时流媒体(需要稳定吞吐,不抖动)
小经验:BBR v3 已经进入 Linux 主线,我建议生产环境至少用 BBR v1 以上。BBR 也有缺点——它在公平性上不如 CUBIC,多流竞争时容易“抢跑”。
Vegas:老派的“基于延迟”算法
Vegas 不属于主流算法,但在低延迟场景下仍有价值。它通过比较“实际吞吐”和“预期吞吐”来判断网络是否拥塞,而不是等丢包。当实际吞吐低于预期时,说明网络开始排队,Vegas 就减小窗口。说白了,它想在丢包发生前就踩刹车。
我曾经在金融交易系统的低延迟链路(机房之间光纤直连,RTT < 1ms)试过 Vegas,结果延迟抖动比 CUBIC 低了 60%。不过 Vegas 在跨互联网链路上基本没法用——非拥塞丢包会误判为拥塞,导致窗口越来越小。
Vegas 的适用场景
- 低延迟数据中心互连(RTT < 5ms,丢包极少)
- 对延迟抖动敏感的实时应用(高频交易、VoIP)
- 前向链路带宽极不对称的场景(如 LTE 上行受限)
避坑指南:我曾经在跨 AWS 区域(RTT 60ms)启用 Vegas,结果吞吐只有 CUBIC 的 20%。Vegas 对非拥塞丢包和 RTT 突变非常敏感,千万不要在互联网公网上用。
三算法对比表
| 维度 | CUBIC | BBR | Vegas |
|---|---|---|---|
| 拥塞信号 | 丢包 | 带宽 & RTT 探测 | RTT 变化(排队延迟) |
| 对丢包敏感度 | 高 | 低 | 高(误判严重) |
| 公平性 | 优秀 | 一般(多流竞争时偏激进) | 良好(但需同步 RTT 基线) |
| 延迟抖动 | 中 | 低(BBR 有 pacing) | 极低 |
| 典型适用环境 | 有线、大延迟、高带宽 | 无线、高丢包、动态链路 | 低延迟数据中心、固定短 RTT |
| Linux 默认 | 是 | 需手动加载模块 | 内核包含但需启用 |
如何选择?一张决策流程图
下面的图总结了网络环境到算法选择的逻辑。你可以把它贴在工位上,每次做网络优化时照着走一遍。
实战配置:如何切换算法
Linux 下切换拥塞控制算法很简单。我一般先用 sysctl 查看当前可用模块:
# 查看当前可用拥塞控制算法
sysctl net.ipv4.tcp_available_congestion_control
# 查看当前使用的算法
sysctl net.ipv4.tcp_congestion_control
如果没有 BBR,先加载模块,再切换:
# 加载 BBR 模块(如果内核版本支持 4.9+)
modprobe tcp_bbr
# 临时切换
sysctl -w net.ipv4.tcp_congestion_control=bbr
# 永久生效(写入 /etc/sysctl.conf)
echo "net.ipv4.tcp_congestion_control = bbr" >> /etc/sysctl.conf
小技巧:如果想在启动容器时使用 BBR,可以在 Docker 容器的启动参数加 --sysctl net.ipv4.tcp_congestion_control=bbr。不过要注意宿主内核必须支持。
总结一句话
没有最好的算法,只有最合适的场景。CUBIC 是“公平的保底”,BBR 是“抗丢包的尖兵”,Vegas 是“低延迟的偏执狂”。我自己的经验是:互联网服务优先上 BBR,内网服务保持 CUBIC,高频交易上 Vegas。按照上面的决策图走一遍,一般不会翻车。