TCP的拥塞控制

  • 拥塞窗口

在TCP发送端有3个窗口,分别是发送窗口,滑动窗口,拥塞窗口。发送窗口就是实际生效的窗口,发送窗口的大小等于滑动窗口和拥塞窗口中的较小者。

  • 拥塞控制

发送速率按倍数指数增加,当发生拥塞时速率减半

  • 拥塞避免

发送速率按MSS数量线性增加,每经过一个RTT增中1个MSS,当发生拥塞时速率降低一个MSS。

  • 慢启动

在慢启动开始时执行拥塞控制快速达到最大带宽,然后降低发送速率再以拥塞避免的方式缓慢增加发送速率。 在执行拥塞避免的过程中会不断达到最大发送速率进入拥塞状态,然后再降低速率,如此往复发送速率会出现矩齿形波动。

  • 快速恢复

新版TCP(Reno)选择跳过丢包后收到三次重复ACK的慢启动过程,直接进入拥塞避免阶段,这就是所谓的快速恢复,但是超时重传后还是会进入慢启动的。

  • 快速重传

在TCP确认机制中已经讲过快速重传,当快速重传触发时也会同步触发拥塞控制,从而将拥塞窗口减半,对于CUBIC算法则窗口大小会减少20%至30%,BBR算法则窗口大小会减少10%至20%。

  • ECN

当即将发生丢包或延迟增加时路由器或者防火墙提前通过ECN标志告诉发送方即将发生拥塞,从而降低发送速率以避免实际发生丢包或延迟增加。相当于拥塞预警标志。 这个标志会同时出现在IP报头和TCP报头中,以便于路由器操作。 IP报文中的ECN标志用于路由器向接收方发送的报文中携带拥塞预警标志,TCP报文中的ECN标志用于接收方把路由器在IP报文中的拥塞预警反映给发送方。 ECN可以实现零丢包,低时延的的拥塞控制,但支持ECN的防火墙,路由器,交换机非常少,华为也只有部分支持智能无损网络的交换设备才支持。

参考:https://segmentfault.com/a/1190000044452754

  • CUBIC

Reno算法的速率提升还是太慢了,尤其对于短时连接,数据发完了还没达到最大速率。CUBIC使用三次方函数进一步提高拥塞避免阶段的速率提升速度(取代之前的线性提速),同时解决了RTT公平性问题。 传统的拥塞避免算法(Reno)基于RTT周期来增加发送速率,RTT越小的连接速度启动越快,这样对高延迟连接就很不公平,CUBIC的拥塞避免不再与RTT挂钩而是与固定时间挂钩。

  • BBR

BBR会周期性的探测当前的实际延迟(RTprop)和带宽(BtlBw),RTprop和BtlBw是BBR引入的两个术语,表示当前网络的物理延迟和带宽。BBR会周期性的提高发送速率(25%)来探测BtlBw有没有增加,降低发送速率(inflight = 4,未确认包为4)来探测RTprop有没有减少。使用RTprop剩以BtlBw得到BDP(带宽延迟积),BDP表示正在飞行中(在传输管道中)的数据量,也即是未确认的数据量。当inflight大于BDP时cwnd会变满,会停止发送数据。

现代网络设备都有很大的队列缓存,当发生拥塞时数据会排队,然后就会引起延迟增加,不利于延迟敏感应用,使用BBR算法可以避免拥塞时产生的延迟增加或网络中断。

BBR算法probeBw周期是8个RTT,在稳定状态始终执行probeBw,这8个RTT周期对应的pacing_gain系数分别是1.25,0.75,1,1,1,1,1(probeBw就是通过控制pacing_gain来执行的),即1个RTT加速,1个RTT减速,剩余4个RTT匀速发送。(这个周期是参考网上别人的笔记和deepseek(怀疑deepseek也是网上抄来的),具体是不是这样还要结合源代码和IETF文档来验证) 但是probeRTT是每10s执行一次(固为RTTprop变化频率低,且测量RTTprop会影响带宽)。 BBRv1已经合并linux主线分支,但BBRv3尚没有合并(截止linux 6.15 RC5),v2应该只是实验版本不会对外发布,v3包含v2的功能。BBRv3修复了诸多bug,降低了重传序和延迟,与Cubic更好的共存,支持ECN等。

https://datatracker.ietf.org/doc/draft-ietf-ccwg-bbr/02/ https://zhuanlan.zhihu.com/p/142835569 https://cloud.tencent.com/developer/article/1482633 https://zhuanlan.zhihu.com/p/675308313

Views: 1