TCP 拥塞控制算法详解:CUBIC、BBR 及传统算法
目录
- [CUBIC 拥塞控制算法](#CUBIC 拥塞控制算法)
- [BBR 拥塞控制算法](#BBR 拥塞控制算法)
- [CUBIC 与 BBR 对比总结](#CUBIC 与 BBR 对比总结)
- [传统算法:TCP Tahoe](#传统算法:TCP Tahoe)
- [传统算法:TCP Reno](#传统算法:TCP Reno)
- [传统算法:TCP NewReno](#传统算法:TCP NewReno)
- [传统算法:TCP SACK](#传统算法:TCP SACK)
- 传统算法总结对比
- 从传统到现代的演进
一、CUBIC 拥塞控制算法
1.1 背景
CUBIC 是一种基于窗口 的拥塞控制算法,是对传统 BIC(Binary Increase Congestion Control) 的改进。在 Linux 内核中被广泛采用(自 Linux 2.6.19 引入),尤其在**高带宽、高延迟(长肥网络,LFN)**环境中表现良好,是许多现代操作系统的默认 TCP 拥塞控制算法。
1.2 特点
- 以时间为基准的窗口增长 :使用立方函数调整拥塞窗口(cwnd),而非线性或指数增长。
- 对高 BDP 网络友好:适合高速、长距离网络。
- 窗口增长与丢包相关,但不完全依赖丢包作为拥塞的唯一信号。
1.3 工作原理
- 发生丢包时 :CUBIC 将拥塞窗口降至 W_max × β(β 一般约 0.7)。
- 之后 :不再线性增加 cwnd,而是按三次函数 (关于时间差 t)快速增长,较快接近上次最大窗口 W_max,再缓慢逼近新平衡点。
- 公式 (简化):
W(t) = C(t − K)³ + W_max
其中:W(t) 为 t 时刻的拥塞窗口;C 为缩放常数;K 为达到 W_max 所需时间;t 为自上次丢包以来的时间。
1.4 优点
- 在高带宽延迟网络中性能优于传统算法。
- 可扩展性好,适合数据中心和互联网骨干网。
1.5 缺点
- 仍主要依赖丢包作为拥塞信号,难以区分排队延迟与真正拥塞。
- 在存在较大缓冲队列的网络中可能引起较高延迟(bufferbloat)。
二、BBR 拥塞控制算法
2.1 背景
BBR(Bottleneck Bandwidth and RTT) 由 Google 提出(2016 年),旨在解决传统基于丢包 的算法(如 CUBIC)在高延迟、高带宽环境下效率低下的问题,并改善 bufferbloat。
2.2 特点
- 不依赖丢包 作为拥塞判断,而是基于**瓶颈带宽(BtlBw)和往返时延(RTprop)**动态调整发送速率。
- 主动探测网络带宽和最小 RTT,通过建模网络状态实现高效传输。
- 显著减少排队延迟,提高响应速度和吞吐量。
2.3 工作原理
BBR 周期性地在两种模式之间切换:
- PROBE_BW(带宽探测):逐步增加发送速率以探测可用带宽。
- PROBE_RTT(最小 RTT 探测):定期降低发送速率以测量最小 RTT(反映无排队时的网络延迟)。
BBR 控制两个关键参数:
- BtlBw:当前路径所能承载的最大数据传输率(瓶颈带宽估计)。
- RTprop:路径上的最短往返时间(最小 RTT)。
拥塞窗口的调整不直接依据丢包,而是使发送速率尽量匹配估计的瓶颈带宽,同时避免过多排队延迟。
2.4 优点
- 在高带宽、高延迟、高缓冲网络中性能优越。
- 降低网络延迟和抖动,提升用户体验。
- 减少因拥塞窗口过大造成的 bufferbloat。
- 特别适用于视频流、大文件传输等对带宽敏感的场景。
2.5 缺点
- 多 BBR 流竞争时可能存在公平性问题。
- 部署需要操作系统支持(Linux kernel ≥ 4.9 支持较好)。
- 部分网络设备对非传统拥塞控制算法支持不佳。
三、CUBIC 与 BBR 对比总结
| 特性 | CUBIC | BBR |
|---|---|---|
| 拥塞判断依据 | 丢包 | 带宽 & 延迟(不依赖丢包) |
| 拥塞窗口增长方式 | 基于时间的立方函数 | 基于带宽/延迟模型的速率控制 |
| 对延迟的敏感性 | 较低,易受 bufferbloat 影响 | 高,能显著降低延迟 |
| 适用场景 | 高带宽延迟网络、通用场景 | 高速网络、实时业务、视频流、云应用 |
| 公平性 | 较好 | 多 BBR 流间可能存在竞争问题 |
| 默认支持 | Linux 默认(老版本) | 需手动开启(Linux 4.9+ 支持) |
四、传统算法:TCP Tahoe
4.1 背景
Tahoe 是最早的 TCP 拥塞控制算法之一(约 1988 年),是 TCP Reno 的前身,首次引入拥塞控制的基本思想。
4.2 核心机制
- 慢启动(Slow Start) :初始 cwnd 较小,每经过一个 RTT,cwnd 翻倍(指数增长),直到达到慢启动阈值 ssthresh。
- 拥塞避免(Congestion Avoidance) :当 cwnd ≥ ssthresh 后,改为线性增长(每 RTT 加 1)。
- 快速重传(Fast Retransmit) :收到 3 个重复 ACK 时,立即重传丢失的数据包,无需等待超时。
- 发生丢包时 :将 ssthresh 减半 ;将 cwnd 设为 1,重新进入慢启动。
4.3 缺点
- 一旦检测到丢包就回到慢启动,性能急剧下降。
- 没有「快速恢复」机制,带宽利用率不高。
五、传统算法:TCP Reno
5.1 背景
Reno 在 Tahoe 基础上加入快速恢复,约 1990 年前后提出,广泛用于早期 Internet。
5.2 核心机制
继承 Tahoe 的慢启动、拥塞避免和快速重传,并新增:
- 快速恢复(Fast Recovery) :
当收到 3 个重复 ACK 时:- 设置 ssthresh = max(cwnd/2, 2);
- 设置 cwnd = ssthresh;
- 每收到一个重复 ACK,cwnd 增加 1(有上限);
- 重传丢失报文;
- 当收到新 ACK(确认新数据)时,退出快速恢复,cwnd 设为 ssthresh,进入拥塞避免。
- 超时处理 :若发生超时重传,ssthresh 设为 cwnd/2,cwnd 重置为 1,重新进入慢启动。
5.3 优点与缺点
- 优点:相比 Tahoe,丢包恢复更快,网络利用率更高。
- 缺点 :对同一窗口内多个包丢失处理有限;在高 BDP 网络中扩展性不足;仍基于「丢包=拥塞」模型。
六、传统算法:TCP NewReno
6.1 背景
NewReno 改进 Reno 在同一窗口内多包丢失时的表现(RFC 2582)。
6.2 核心机制
- Reno 在快速恢复过程中只能恢复一个丢包;若有多个丢包,会多次触发快速重传和窗口重置。
- NewReno 修改快速恢复逻辑,使发送方在一次 fast recovery 中可连续重传所有丢失的包,直到全部被确认才退出恢复状态。
6.3 优点与缺点
- 优点:多包丢失场景下吞吐量更高;向后兼容 Reno。
- 缺点:实现更复杂;仍受限于丢包检测,难以很好适应高带宽、低丢包率网络。
七、传统算法:TCP SACK
7.1 背景
SACK(Selective Acknowledgment)不是完整的拥塞控制算法,而是配合 Reno/NewReno 的增强机制(RFC 2018、RFC 2883)。
7.2 工作机制
- 接收方通过 TCP 选项中的 SACK 字段报告已收到的非连续数据块。
- 发送方据此只重传真正丢失的段,而不是从最近确认点之后的所有数据。
7.3 优点与缺点
- 优点:大幅改善多包丢失的恢复效率;与 NewReno 结合形成「NewReno + SACK」效果更好。
- 缺点:协议更复杂;并非所有设备都支持 SACK。
八、传统算法总结对比
| 算法 | 拥塞控制机制 | 多包丢失处理 | 快速恢复 | 是否考虑延迟 | 出现年代 |
|---|---|---|---|---|---|
| Tahoe | 慢启动 + 拥塞避免 + 快速重传 | 差 | ❌ | ❌ | 1988 |
| Reno | + 快速恢复 | 一般 | ✅ | ❌ | ~1990 |
| NewReno | 改进快速恢复,支持多包丢失 | 好 | ✅ | ❌ | 1999 (RFC) |
| SACK(+) | 提供细粒度重传信息 | 更好(配合) | ✅ | ❌ | 1996+ |
传统算法的总体评价
- 优点:简单、易实现、广泛部署;在低带宽、低延迟、丢包频繁的网络中有效;奠定了后续发展基础。
- 缺点:基于「丢包=拥塞」的保守模型;cwnd 调整反应较慢,吞吐量易剧烈波动;忽略延迟变化,易导致 bufferbloat;难以应对数据中心、视频流、云服务等高要求场景。
九、从传统到现代的演进
Tahoe → Reno → NewReno (+SACK) → CUBIC → BBR
↑ ↑
传统丢包驱动模型 现代模型驱动/测量驱动
CUBIC 和 BBR 代表了两种不同理念:前者仍以丢包驱动 为主,后者采用测量驱动(带宽与 RTT)的模型。随着对实时性和高带宽需求的增长,BBR 等新一代算法得到越来越广泛的应用。实际部署中应根据网络特点和业务需求选择合适的拥塞控制策略。