【学习笔记】浅析TCP的拥塞控制

来源:互联网 发布:数据分析工作计划 编辑:程序博客网 时间:2024/04/28 23:37

这两天看了下基于TCP的端到端的拥塞控制机制,今天下午刚好无事就大概梳理了一下。

其主要流程为慢启动->拥塞避免->快速重传(快速恢复)。


拥塞控制概述

拥塞控制主要依赖于cwnd(拥塞窗口)来进行控制,另外一个rwnd(对端通告的接收窗口)负责流量控制,。窗口值的大小代表能够发出去但还未收到ACK的最大数据报文量。这个窗口值越大数据的发送速度也越快,同样也越容易导致网络拥塞;而如果这个值过小,会导致传送速率下降,当cwnd下降为1时,则退化为一个停等协议,每发送一个数据需要等待对端的确认才能继续发送下一个数据包。所以TCP的拥塞控制算法要做的就是在这之间找一个适当的窗口值,让网络吞吐效率最大化而不产生拥塞。

当同时考虑拥塞控制和流量控制时,TCP真正的发送窗口=min(rwnd,cwnd)。但是rwnd是由对端确定的,网络环境对其没有影响,所以我们这里暂时不对其进行讨论。TCP中cwnd的单位是字节,我们设TCP按MSS(最大报文段)=[上次发送数据量的大小]来发送数据。

慢启动

最开始TCP中并没有设置慢启动时,连接一建立便会向网络发送大量数据,当路由的缓存满时,继续发送数据便导致了网络拥塞(延时,丢包等)。为了避免以上情况,我们便要求连接建立之后,根据网络情况逐步的增加发送的数据量,以避免上述情况发生,这边是慢启动。

具体步骤是将cwnd初始化为1,之后每次收到对端的确认信息便将长度翻倍(即增加一个MSS),这样cwnd的值便按网络往返时间(Round-Trip Time,RTT)呈指数增长,我们将其称作指数增长期。其下面是一个简单的示意图:
  开始 cwnd = 1 ACK;
经过第一个RTT cwnd = 1*2 = 2ACK;
经过第二个RTT cwnd = 2*2 = 4ACK;
经过第三个RTT cwnd = 4*2 = 8ACK;
……
独自占满带宽(W)的时间为RTT*logW,此处看来慢启动其实并没有那么慢。

拥塞避免

从慢启动看,cwnd的增长其实是很快的,但因为带宽有限,肯定不能让它无休止的增加下去,于是就出现了慢启动门限(ssthresh)变量,当cwnd超过该值时,慢启动阶段结束,进入拥塞避免阶段(对于大多数TCP的实现,ssthresh=65536)。此时的cwnd不再指数增长,而是开始加法增大。每次报文被确认时,cwnd的长度增加1,此时cwnd随着RTT呈线性增长。
【这样就可以避免增长过快导致网络拥塞,慢慢的增加调整到网络最佳值。——引tcp拥塞控制—w_s_xin】

那么当cwnd继续增加到阈值,发生了网络拥塞,该如何去调整?
首先来看一下TCP是如何判断网络进入了拥塞状态的,TCP认为网络拥塞的重要依据是它重传了报文段。当一个数据包的重传计时器(RTO)超时而没有接受到这个数据的ACK时,TCP认为网络发生了拥塞。【注意:此时只是超时,还未必发生丢包。不过也快了...】

快速重传与快速恢复

接上文,当网络发生了拥塞,则必须对传输进行调整,于是我们引进了快速重传算法,还有快速恢复算法,两者一般一起用。

快速重传的具体判定是这样的:当某个包丢失,连续收到三个相同的ACK时,进入快速恢复阶段。在说明快速恢复之前,先解释一下为何会接收到三个相同的ACK,见下图:


【图引:TCP-SACK的选项—易隐者】
我认为这是一张非常棒的图,直观的说明了问题的原因,其中Client只当收到一个包才会返回一个ACK(返回重复的ACK也要等到新的数据包到来)。

那我们继续说快速恢复的机制,快速恢复的思想是“数据包守恒”原则,即同一时刻在网络中存在的数据包数量是恒定的,只有老数据包离开了网络,新的数据包才能进入。如果发送方收到了一个重复的ACK,说明有一个包离开了网络,于是cwnd+1*MSS。 
【如果能够严格按照该原则那么网络中很少会发生拥塞,事实上拥塞控制的目的也就在修正违反该原则的地方。——引tcp拥塞控制—w_s_xin】

所以综合以上,主要步骤为:
当收到3个重复ACK时,把ssthresh设置为cwnd的一半,把cwnd设置为ssthresh+3*MSS。(加3的原因是因为收到3个重复的ACK,表明有3个老数据包离开了网络。)
重传丢失的数据(将之前丢失的数据打包一次扔过去)。
再收到重复的ACK时,cwnd += MSS。
当收到新的数据包的ACK时,把cwnd设置为第一步中的ssthresh的值(因为该ACK确认了新数据,说明从重复ACK时的数据都已收到,该恢复过程已经结束),再次进入拥塞避免状态。
【注:完成快速重传后使用快速恢复算法,进入的是拥塞避免阶段而非慢启动阶段。——TCP快速重传与快速恢复原理分析—zhangsk】


用下面的图来进行小结:


【图引:百度图片搜索】

【我们现在回顾一下拥塞避免与快速重传算法,其原理可以归纳为AIMD,即加法增大,乘法减小。可以看出TCP的该原则可以较好地保证流之间的公平性,因为一旦出现丢包,那么立即减半退避,可以给其他新建的流留有足够的空间,从而保证整个的公平性。——引tcp拥塞控制—w_s_xin】

选择性确认技术

但是在上文中,快速重发存在一个问题,就是丢包后重新发送的不仅仅是丢失的数据包,而是该包及所有之后的数据包,即之前图中的data-2,data-3,data-4,data-5,而这些数据包中,对端事实上已经接收到除data-2以外的其他包,如此导致的直接问题就是TCP的吞吐量下降。为此,选择性确认(SACK)技术应运而生。

SACK使TCP只需重发交互过程中丢失的包,不用发送后续所有的包,并提供对应机制使接受端通知发送端哪些数据丢失,哪些数据重发了,哪些数据已经提前收到。如此大大提升了收发效率。其原理简图如下:


【图引:TCP-SACK的选项—易隐者】


参考资料

tcp拥塞控制—w_s_xin
TCP SACK选项—易隐者
拥塞控制机制(一)—鱼思故渊
TCP快速重传与快速恢复原理分析—zhangsk
0 0
原创粉丝点击