🎯 课程摘要:TCP 拥塞控制 (congestion control) 是防止过多数据注入网络的全局性机制,核心由四种算法构成:慢开始 (slow start)、拥塞避免 (congestion avoidance)、快重传 (fast retransmit)、快恢复 (fast recovery)。通过维护拥塞窗口 CWND 和慢开始门限 ssthresh,根据超时重传或三个重复确认来调整发送速率。网际层则通过主动队列管理 AQM(如 RED)配合避免全局同步。
- 概念定义:在某段时间,若对网络中某一资源的需求超过了该资源所能提供的可用部分,网络性能就要变坏,这种情况称为拥塞 (congestion)。
- 网络资源:链路容量(带宽)、交换节点中的缓存和处理机等。
- ⚠️ 重点/考点:若出现拥塞而不进行控制,整个网络的吞吐量将随输入负载的增大而下降;当输入负载增大到某一数值时,吞吐量减小为零,网络无法工作,即死锁。
| 区域 | 输入负载变化 | 吞吐量变化 | 状态 |
|---|
| 理想控制 | 增大(未饱和) | 等于输入负载(45°斜线) | 正常 |
| 理想控制 | 超过限度 | 保持水平(饱和) | 正常 |
| 轻度拥塞 | 增大 | 增长率逐渐减小 | 轻度拥塞 |
| 拥塞状态 | 到达某一数值 | 反而随输入负载增大而减小 | 拥塞 |
| 无控制 | 继续增大 | 减小为零 | 死锁 |
| 对比项 | 流量控制 (flow control) | 拥塞控制 (congestion control) |
|---|
| 任务 | 防止发送方超过接收方接收能力 | 防止过多数据注入网络 |
| 控制依据 | 接收方的接收能力 | 各方面因素(全局) |
| 范围 | 点对点通信 | 全局性问题 |
| 涉及对象 | 特定发送方与接收方 | 所有主机、路由器、存储转发过程等 |
| 控制方 | 接收方控制发送方 | 源点按算法自行控制发送速率 |
- 开环控制:用良好设计从一开始保证问题不发生,系统运行后不再调整;适合流量特征可准确规定且性能要求可事先获得的场景。
- 闭环控制:基于反馈的控制方法,包括三部分:①监测网络拥塞在何时何地发生;②把拥塞信息传送到可采取行动的地方;③调整网络运行以解决问题。适合流量特征不能准确描述或网络不提供资源预留的场景。
- ⚠️ 重点/考点:Internet 不提供资源预留机制且流量特征不能准确描述,因此主要采用闭环控制。
- 衡量拥塞的指标:缓存溢出丢弃分组百分比、路由器平均队列长度、超时重传分组数量、平均分组时延及其标准差等;这些指标上升标志着拥塞程度增大。
- 反馈形式分类:
- 显式反馈:拥塞节点(路由器)向源点提供显式反馈信息,如 ICMP 源站抑制报文,或在转发分组中保留字段表示拥塞状态。
- 隐式反馈:源点通过观察网络行为(超时重传、RTT)推断是否拥塞,无需拥塞节点提供显式信息。
- ⚠️ 重点/考点:TCP 采用隐式反馈算法,在运输层实现拥塞控制。
- 假设条件:
- 数据单方向传送,另一方向只传送确认;
- 接收方总有足够大接收缓存,发送窗口仅由网络拥塞程度决定(不考虑流量控制);
- 以 TCP 最大报文段长度 MSS(数据载荷字节数)为单位。
- 状态变量:
| 变量 | 含义 | 维护方 |
|---|
| CWND | 拥塞窗口 | 发送方 |
| RWND | 接收窗口 | 接收方 |
| SWND | 发送窗口 = min(CWND, RWND) | 发送方 |
| ssthresh | 慢开始门限 | 发送方 |
- 判断拥塞的依据:没有按时收到确认报文段而产生超时重传(现代通信线路误码率低,超时重传很可能是路由器繁忙丢弃分组所致)。
- 算法选择规则:
- CWND < ssthresh → 使用慢开始算法
- CWND = ssthresh → 二者皆可
- CWND > ssthresh → 使用拥塞避免算法
- 慢开始:CWND 初始值设为 1,每个传输轮次结束后 CWND 按指数规律增长(+1、+2、+4、+8…)。
- 拥塞避免:当 CWND 达到 ssthresh 时改用,每个传输轮次结束后 CWND 线性加 1。
- 传输轮次:发送方把 CWND 允许发送的报文段连续发送出去,并收到对已发送最后一个报文段的确认;一个轮次经历的时间即 RTT。
- ⚠️ 重点/考点:"慢开始"是指一开始向网络注入的报文段少,而不是指 CWND 增长速度慢;"拥塞避免"并非完全避免拥塞,而是使 CWND 线性增长,使网络不易出现拥塞。
- 超时重传时的处理:
- ssthresh = 当前 CWND / 2
- CWND = 1
- 重新开始执行慢开始算法
- 快重传:要求接收方不等待自己发送数据时才捎带确认,而是立即发送确认;即使收到失序报文段也立即发送对已收到报文段的重复确认。发送方一旦收到三个连续的重复确认,就立即重传相应报文段,而不等重传计时器超时。
- 快恢复:发送方收到三个重复确认时,知道只是丢失个别报文段(并非拥塞),不启动慢开始,而是:
- ssthresh = 当前 CWND / 2
- CWND = ssthresh(也有的实现取 CWND = 新 ssthresh + 3)
- 开始执行拥塞避免算法
- 快恢复 CWND 增大的理由:收到三个重复确认表明已有三个报文段离开网络、停留在接收方缓存中,网络中报文段减少了三个,故可适当增大 CWND。
- ⚠️ 重点/考点:慢开始和拥塞避免于 1988 年提出(TCP Tahoe 版本);快重传和快恢复于 1990 年增加(TCP Reno 版本);使用快重传可使整个网络吞吐量提高约 20%。
| 传输轮次 | 算法 | 本轮发送 | 确认后 CWND |
|---|
| 初始 | — | — | 1 |
| 1 | 慢开始 | 0号 | 2 |
| 2 | 慢开始 | 1~2号 | 4 |
| 3 | 慢开始 | 3~6号 | 8 |
| 4 | 慢开始 | 7~14号 | 16(达到 ssthresh) |
| 5 | 拥塞避免 | 15~30号 | 17 |
| 6 | 拥塞避免 | 31~47号 | 18 |
| … | 拥塞避免 | … | 线性 +1 |
| n | 拥塞避免 | 171~194号(丢失几个) | 24 → 超时重传 |
| 重置 | — | — | ssthresh=12, CWND=1 |
| 之后 | 慢开始 | — | 1→2→4→8→12(指数) |
| 之后 | 拥塞避免 | — | 12→13→14…(线性) |
- 尾部丢弃策略:路由器输入缓存队列按 FIFO 处理,队列已满后到达的 IP 数据报都被丢弃。当大量 TCP 报文段涌入造成尾部丢弃时,多个 TCP 发送方同时超时重传,同时进入慢开始阶段,称为全局同步,导致全网通信量骤降后又骤增。
- 主动队列管理 AQM (Active Queue Management):1998 年提出,在路由器队列长度达到某阈值(但未满)时就主动丢弃 IP 数据报,以提前降低发送方速率。
- 随机早期检测 RED (Random Early Detection):AQM 的一种实现,维护最小门限和最大门限:
- 平均队列长度 < 最小门限:存入队列;
- 平均队列长度 > 最大门限:丢弃;
- 介于两者之间:按某丢弃概率 p 丢弃(体现随机性)。
- ⚠️ 重点/考点:RFC 7567(2015 年)已将 RFC 2309 列为陈旧,不再推荐使用 RED;但路由器进行主动队列管理仍必要,替代算法尚在实验阶段,无 IETF 标准。
- 拥塞控制是全局性问题,区别于点对点的流量控制;TCP 采用隐式反馈(超时重传)判断拥塞。
- 四种算法:慢开始(指数)、拥塞避免(线性)、快重传(3 个重复确认立即重传)、快恢复(CWND 减半而非降为 1)。
- 超时重传 → ssthresh=CWND/2、CWND=1、重启慢开始;三个重复确认 → ssthresh=CWND/2、CWND=ssthresh、执行拥塞避免。
- 发送窗口 SWND = min(CWND, RWND),最终发送速率受两者共同约束。
- 网际层通过 AQM/RED 缓解尾部丢弃引发的全局同步问题。
- (2009 真题)TCP 连接 cwnd=16 时超时,后续 cwnd 变化?答:ssthresh=8、cwnd=1,慢开始指数增长到 8 后拥塞避免线性增长,第 3 轮次后 cwnd=4,第 4 轮次后 cwnd=9。
- (2014 真题)接收窗口 RWND=10KB,则发送窗口 SWND 最大值?答:SWND=min(CWND, RWND)≤10KB,选 A。
- (2020 真题)cwnd 从 8KB 增长到 20KB 最长耗时?答:处于拥塞避免阶段,线性加 1 共 12 个轮次,RTT=2ms,耗时 24ms。
- 慢开始"慢"的含义是什么?快恢复为何不把 CWND 降为 1?
- 尾部丢弃策略为什么会引发全局同步?