0%
boxmoe_header_banner_img

加载中

CS168 Congestion Control 1


avatar
akurisu 2026年5月23日 2026年5月23日 124

本文主要讨论Congestion Control Protocols中的Dynamic Adjustment,而不是Pricing和Reservation。

Host-Based Dynamic Adjustment

每一个主机遵循算法如下:

  1. 选取一个初始速率R
  2. 尝试着以R为速率发送一段时间
    • 有没有经历拥塞?
    • 有,降低R
    • 没有,增加R
    • 重复这个过程

    这个算法显然还有一些困难需要解决:

    • 怎么选取初始速率?
    • 怎么检查拥塞?
    • 怎么增减?

    下面来逐渐解决这三个问题。

Detecting Congestion

由两个方法构成

Loss-based (基于丢包的检测)

TCP使用
优点:

  1. 信号明确:数据包只有丢与被丢两种情况
  2. 天然兼容TCP: TCP本身就需要检测丢包,无需额外新增机制

缺点:

  1. 丢包 ≠ 拥塞:校验和错误,链路误码等也可以导致丢包
  2. 容易误判
  3. 反馈滞后,检测丢包的时候网络队列已经占满 (如果是由于网络队列丢包的,那么当检测到的时候网络队列已经占满),相当于出事了你才去补救,显然是不及时的。

(丢包:当发送方超时没有收到ACK,或者收到3次重复的ACK时判定为丢包)

Delay-based (基于延迟的检测)

TCP不使用
实现较为困难:

  1. 延迟波动复杂
  2. 长期难以精确实现

Discovering an Initial Rate

  1. 从较小值开始
  2. 快速递增 (不然会造成资源浪费)

如果线性增长,会浪费带宽、
所以我们要使用指数函数来增长

How can we Increase and Decrease? (速率调整)

  1. 快速调整 R -> 2R , R -> R / 2
  2. 慢速调整 R -> R + 1 , R -> R – 1

排列组合有四种组合策略:

  1. AIAD 加法增 加法减
  2. AIMD 加法增 乘法减 TCP标准算法(避免拥塞,实现带宽利用率与公平性的平衡)
  3. MIAD 乘法增 加法减
  4. MIMD 乘法增 乘法减

至于为什么AIMD实现了最好的速率调整,直观上很容易理解,课程给出了一张非常好的图如下,非常便于理解,但是具体证明在此不予赘述,可以自行搜索
屏幕截图 2026-05-22 001445

Review: Setting Window Size

发送方会维护一个大小为W的窗口,用来控制同时再网络中传输但是没有确认的数据包个数。
怎么确定这个大小W呢?

  1. 不超载接收方 (流量控制)

接收方会通过接收窗口(RWND)告知发送方自己剩余的缓冲区空间,这里的接收窗口实际上是一个数值。发送方不能超过RWND允许的数据量。

  1. 不超载网络链路 (拥塞控制)

发送方通过拥塞窗口 (CWND) 控制发送量,当然他也是个数值。这个窗口由拥塞控制算法动态调整,避免网络发生拥塞。

W = min(RWND, CWND) 取二者的最小值,很多时候RWND > CWND, 这时候W由拥塞窗口决定

Event Driven Instead of RTT

最理想情况下,每个迭代持续一个RTT (往返时间),因为RTT是数据包从发送方到接收方再返回确认的时间,每经过一个RTT,发送方就能接收反馈。
但是RTT难以精确测量,并且会动态波动,因此不能直接使用。所以我们不使用RTT,而是事件驱动更新机制,有以下方式更新:

  1. 收到新数据的ACK -> 说明没有拥塞,CWND增大 (慢启动指数增长或拥塞避免时线性增长)
  2. 收到3个重复的ACK -> 说明大概率有单包丢失了,但不算特别严重 -> 执行乘性减将CWND降低,快速恢复。
  3. 超时计时器到期,判定丢包 -> 说明属于较为严重的网络拥塞 -> 因为太过严重,将CWND重新重置为初始值,重新从慢启动开始。

下面叙述一下Event-Driven Slow Start:
这里是慢启动阶段:
每次收到一个ACK,可以滑动窗口向前滑动 (已应答就不在窗口内了),发送一个新包,CWND加1,综合来看每收到一个ACK,总共可以发送2个新包,这等效于经过一个理想的RTT然后CWND直接翻倍的增长规律。

SSTHRESH (慢启动阈值)

SSTHRESH 一开始会被设置为一个较大值,TCP检测到丢包事件后,立即更新SSTHRESH:
SSTHRESH = 当前CWND / 2
这里的CWND指的时发包瞬间拥塞窗口的大小,然后除以2作为后续的安全带宽参考。

  • CWND < SSTHRESH 慢启动阶段 (指数增长,符合上面的叙述,宏观上等价于过一个RTT然后CWND翻倍)
  • CWND >= SSTHRESH 进入拥塞避免阶段 (线性增长,每收到一个ACK,CWND += 1 / CWND,宏观上等价于没经过一个RTT,CWND += 1)

以上的1均为报文数 (packet),如果用字节数 (byte) 表示CWND需要结合MSS,把1替换为MSS进行计算。(cwnd += MSS * MSS / cwnd)



评论(0)

查看评论列表

暂无评论


发表评论

表情 颜文字

插入代码
后退
前进
刷新
复制
粘贴
全选
删除
返回首页
0%
目录
顶部
底部
📖 文章导读