TCP拥塞控制详解

1. 拥塞控制概述

1.1 什么是拥塞

拥塞是指网络中出现大量数据包堆积,导致网络性能下降的现象。

**拥塞表现**:

  • 数据包延迟增加

  • 丢包率上升

  • 网络吞吐量下降

  • 甚至造成网络瘫痪

1.2 拥塞控制 vs 流量控制

**流量控制**:

  • 端到端的控制

  • 防止发送方淹没接收方

  • 基于接收方缓冲区大小(rwnd)

**拥塞控制**:

  • 网络层面的控制

  • 防止发送方过多数据注入网络

  • 基于网络拥塞程度(cwnd)

1.3 拥塞窗口(cwnd)

```

发送窗口 = min(rwnd, cwnd)

  • rwnd:接收窗口,接收方告知

  • cwnd:拥塞窗口,发送方自己控制

```

2. 慢启动与拥塞避免

2.1 慢启动

**原理**:

  • 连接开始时,cwnd初始化为一个较小的值

  • 每收到一个ACK,cwnd增加一个MSS

  • 指数增长,快速探测网络容量

**公式**:

```

每收到一个ACK:cwnd = cwnd + MSS

等同于每RTT:cwnd = cwnd * 2

```

**慢启动阈值(ssthresh)**:

  • 当cwnd达到ssthresh时,进入拥塞避免

  • 典型初始值:65535字节

**实例**:

```

初始:cwnd=1 MSS, ssthresh=64 MSS

第1个RTT:cwnd=2 MSS

第2个RTT:cwnd=4 MSS

第3个RTT:cwnd=8 MSS

第4个RTT:cwnd=16 MSS

...

直到cwnd达到ssthresh

```

2.2 拥塞避免

**原理**:

  • cwnd达到ssthresh后进入

  • 每收到一个ACK,cwnd增加(MSS * MSS / cwnd)

  • 线性增长,缓慢探测网络容量

**公式**:

```

每收到一个ACK:cwnd = cwnd + MSS * (MSS / cwnd)

等同于每RTT:cwnd = cwnd + MSS

```

**实例**:

```

场景:cwnd=64 MSS, MSS=1 KB

每收到一个ACK:

cwnd = cwnd + 1 * (1 / 64) = cwnd + 1/64 KB

每RTT(假设64个ACK):

cwnd = 64 + 64 * (1/64) = 65 KB

```

2.3 完整拥塞控制过程

```

连接建立:

cwnd = 1 MSS, ssthresh = 65535

慢启动阶段:

cwnd指数增长,直到达到ssthresh

拥塞避免阶段:

cwnd线性增长

检测到丢包:

ssthresh = cwnd / 2

cwnd = 1 MSS

重新开始慢启动

```

3. 快速重传与快速恢复

3.1 快速重传

**触发条件**:

  • 收到3个或更多重复ACK

  • 说明有数据包丢失,但网络仍可通

**原理**:

  • 不等待超时重传

  • 立即重传丢失的数据包

**流程**:

```

发送方发送1,2,3,4,5

接收方只收到1,2,3,5(4丢失)

接收方发送3个ACK(3)

发送方收到第1个ACK(3):可能是乱序,不重传

发送方收到第2个ACK(3):可能是乱序,不重传

发送方收到第3个ACK(3):确认4丢失,立即重传

```

3.2 快速恢复

**原理**:

  • 快速重传后不进入完全慢启动

  • 轻微调整后继续传输

**传统快速恢复**:

```

  1. 收到3个重复ACK时

  2. ssthresh = cwnd / 2

  3. cwnd = ssthresh + 3 * MSS

  4. 重传丢失数据包

  5. 每收到一个重复ACK:cwnd = cwnd + MSS

  6. 收到新数据的ACK时:cwnd = ssthresh

  7. 进入拥塞避免

```

**实例**:

```

场景:cwnd=100 MSS,检测到丢包

步骤1:ssthresh = 50 MSS

步骤2:cwnd = 50 + 3 = 53 MSS

步骤3:重传丢失数据包

步骤4:收到重复ACK,cwnd = 54 MSS

步骤5:收到新ACK,cwnd = 50 MSS

步骤6:进入拥塞避免

```

4. CUBIC与BBR算法区别

4.1 CUBIC算法

**特点**:

  • Linux默认TCP拥塞控制算法

  • 基于丢包的拥塞控制

  • 使用三次多项式函数调整窗口

**调整公式**:

```

W(t) = C * (t - K)^3 + Wmax

  • C:缩放因子

  • t:当前时间

  • K:窗口达到Wmax的时间

  • Wmax:上次丢包前的窗口大小

```

**优势**:

  • 高带宽高延迟网络表现好

  • 收敛速度快

  • 公平性好

**劣势**:

  • 激进,容易造成bufferbloat

  • 对丢包敏感

4.2 BBR算法

**特点**:

  • Google开发

  • 基于模型的拥塞控制

  • 不依赖丢包检测

**核心原理**:

  • 估计可用带宽

  • 估计往返延迟

  • 调整发送速率

**BBR状态**:

```

  1. Startup(启动):类似于慢启动,快速探测带宽

  2. Drain(排空):排空瓶颈缓冲区

  3. ProbeBW(带宽探测):周期性探测带宽

  4. ProbeRTT(延迟探测):周期性探测延迟

```

**优势**:

  • 低延迟

  • 不受bufferbloat影响

  • 高带宽高延迟网络表现好

**劣势**:

  • 公平性问题

  • 需要较长预热时间

4.3 算法对比

| 特性 | CUBIC | BBR |

|------|-------|-----|

| 拥塞信号 | 丢包 | 延迟/带宽估计 |

| 缓冲区使用 | 积极填充 | 最小化填充 |

| 延迟表现 | 高延迟(bufferbloat) | 低延迟 |

| 丢包敏感度 | 高 | 低 |

| 适用场景 | 短距离网络 | 长距离/高带宽网络 |

| 收敛速度 | 快 | 较慢 |

5. 丢包与延迟对拥塞窗口的影响

5.1 丢包对拥塞窗口的影响

**超时丢包**:

```

影响最大

ssthresh = cwnd / 2

cwnd = 1 MSS

完全重新开始慢启动

```

**3个重复ACK丢包**:

```

影响较小

ssthresh = cwnd / 2

cwnd = ssthresh + 3 * MSS

进入快速恢复

```

**丢包率对吞吐量的影响**:

```

丢包率 = 0.1%:吞吐量影响较小

丢包率 = 1%:吞吐量下降明显

丢包率 = 10%:吞吐量严重下降

```

5.2 延迟对拥塞窗口的影响

**高延迟的影响**:

```

RTT增加,吞吐量下降

带宽-延迟积 = BD = 带宽 * RTT

需要更大的窗口才能利用带宽

```

**实例**:

```

场景:100Mbps带宽,RTT=100ms

带宽-延迟积:

BD = 100Mbps * 100ms = 12.5Mb = 1.25MB

如果cwnd < 1.25MB:

无法充分利用带宽

如果cwnd = 1.25MB:

可以充分利用带宽

```

5.3 bufferbloat问题

**问题描述**:

  • 中间设备(路由器、交换机)缓冲区过大

  • 数据包在缓冲区排队

  • 导致延迟增加,但不会丢包

  • 发送方认为网络正常,继续增加窗口

**影响**:

  • 延迟大幅增加

  • 交互应用体验变差

  • BBR等新算法可以缓解

5.4 实例:拥塞控制全过程

```

场景:1Gbps网络,RTT=20ms,MSS=1KB

步骤1:连接建立

cwnd = 1 MSS = 1 KB

ssthresh = 65535 KB

步骤2:慢启动

cwnd指数增长:1→2→4→8→16→32→64 KB

8个RTT后达到ssthresh

步骤3:拥塞避免

cwnd线性增长:64→65→66→67 KB

步骤4:检测到3个重复ACK

ssthresh = 67 / 2 = 33 KB

cwnd = 33 + 3 = 36 KB

进入快速恢复

步骤5:收到新ACK

cwnd = ssthresh = 33 KB

进入拥塞避免

```

6. 拥塞控制优化建议

6.1 选择合适的算法

```

高带宽高延迟:BBR

短距离网络:CUBIC

混合场景:依情况选择

```

6.2 参数调优

```

tcp_congestion_control:设置拥塞算法

net.ipv4.tcp_ssthresh:调整ssthresh初始值

net.ipv4.tcp_window_scaling:启用窗口扩展

```

6.3 监控与诊断

```

监控cwnd变化

分析丢包率

测量延迟变化

识别拥塞信号

```

7. 总结

TCP拥塞控制是保证网络稳定运行的关键机制:

  1. **慢启动**:快速探测网络容量,指数增长cwnd

  2. **拥塞避免**:达到ssthresh后,线性增长cwnd

  3. **快速重传**:收到3个重复ACK时立即重传

  4. **快速恢复**:轻微调整后继续传输

  5. **CUBIC vs BBR**:基于丢包vs基于模型,各有优劣

  6. **丢包和延迟**:都会影响cwnd调整策略

理解拥塞控制对于网络优化、性能调优和问题排查至关重要。在实际应用中,需要根据网络特性选择合适的拥塞控制算法和参数配置。

相关推荐
切糕师学AI11 小时前
计算机网络层次结构详解:从OSI七层模型到TCP/IP四层模型
网络·tcp/ip·计算机网络
咖喱o11 小时前
IPv6
服务器·前端·网络
IpdataCloud11 小时前
IP查询工具怎么选?在线API vs IP离线库:精度、速度、成本、隐私全对比
服务器·网络·数据库
艾莉丝努力练剑11 小时前
【Linux网络】Linux 网络编程:HTTP(三)HTTP 协议原理
linux·运维·服务器·网络·c++·http
Gauss松鼠会11 小时前
GaussDB(DWS) 资源监控Topsql
java·网络·数据库·算法·oracle·性能优化·gaussdb
minji...11 小时前
Linux 网络基础之网络IP层(十一)私有IP地址和公网IP地址,运营商和全球网络,理解公网
linux·服务器·网络·nat·内网·公网·运营商
Linux运维技术栈11 小时前
一次暴力枚举攻击的防御实践:从 IP 封禁到 WAF,再到 Nginx+Lua 业务层防御
tcp/ip·nginx·安全·lua·云服务器
米高梅狮子11 小时前
01.ELK企业日志分析系统
运维·服务器·网络·数据库·elk·oracle
Ether IC Verifier14 小时前
TCP三次握手与四次挥手详解
网络·网络协议·tcp/ip·计算机网络