TCP拥塞控制

       路由器因无法处理高速率到达的流量而*丢弃数据信息的现象称为拥塞。即使仅有一条通信连接,也可能造成一个甚至多个路由器拥塞,若不采取对策,网络性能将受到很大影响以致瘫痪(最坏情况下甚至形成拥塞崩溃)。为避免或在一定程度上缓解这种状况,TCP规定通信的每一方都要实行拥塞控制机制。

拥塞检测

       针对丢包现象,TCP采取的首要措施是重传,包括超时重传和快速重传。但简单的重传有时候会带来更糟糕的结果。假设当网络处于拥塞崩溃状态时,共用一条网络传输路径的多个TCP连接却重传更多的数据,反而会火上浇油,让本就不堪重负的网络更加拥塞。

TCP拥塞控制

       在TCP中,丢包被用作判断拥塞发生与否的指标,用来衡量是否应该实施相应的响应措施来避免或至少减缓拥塞。其他拥塞探测方法,如时延测量和显式拥塞通知(ECN)会使TCP能在丢包发生前检测拥塞。

调整窗口大小

       TCP的可变滑动窗口机制可以帮助减缓数据的发送量,TCP头部设置了通知窗口大小字段。此外基于网络传输能力的估计,TCP还在发送端引入了一个窗口控制变量,确保发送窗口大小不超过接收端接收能力和网络传输能力,即TCP发送端的发送速率等于接收速率和传输速率中的较小者。

       反映网络传输能力的变量称为拥塞窗口(congestion window),简记为cwnd。因此,发送端的实际可用窗口值W就是接收端通知窗口awnd和拥塞窗口cwnd的较小者:

                                                                      W = min(awnd, cwnd)

       由于网络的变化,通知窗口awnd和拥塞窗口cwnd并不是固定的值,需要根据经验设定并需动态调节。如何设定窗口大小这一问题研究出很多经典算法,如慢启动、快重传、快恢复等。

慢启动

       当一个新的TCP连接建立之初,还无法获知可用的传输资源,所以cwnd的初始值也无法确定(有些系统的缓存容量是预先设定的,这种情况下的cwnd值可以确定)。TCP通过与接收端交换一个数据包就能获得awnd的值,但cwnd不一样,因为网络传输能力一直都在变化。显然,获得cwnd最佳值的唯一方法就是试探——以越来越快的速率不断发送数据,直到出现数据包丢失(或网络拥塞)为止。这时还应考虑立即以可用的最大速率发送(受awnd的限制)或是慢速启动发送。由于多个TCP连接共享网络传输路径,一开始就以全速启动会影响其他连接的传输性能,所以通常会避免过快启动,直至稳定传输后。

       当一个新的TCP连接建立或检测到超时重传(RTO)导致丢包时,需要执行慢启动(TCP发送端长时间处于空闲状态也可能触发慢启动)。慢启动的目的是,使TCP在用拥塞避免探寻更多可用贷款之前得到cwnd值,以及帮助TCP建立ACK时钟。

       TCP以发送一定数目的数据段开始慢启动(在SYN交换之后),称为初始窗口(Initial Window,IW)。IW的值通常设为1SMSS(发送方的最大段大小),也有一些实现根据SMSS的大小赋予不同初始值。

       假设没有出现丢包情况且每个数据包都有对应的ACK,慢启动算法会以二进制指数增加cwnd的值,即由1变2,由2变4,依此类推,在k轮W的值为2^k。这种二进制指数增长看似很快,但与一开始就允许以最大可用速率(接收方通知窗口大小awnd)发送相比仍显缓慢,特别在一些BDP较大的高速网络中,传统慢启动算法要达到链路饱和状态耗时太长,此时需要调整慢启动算法以适应这种高速链路。

慢启动阙值

       慢启动阙值ssthresh和拥塞窗口大小cwnd的关系决定了是采用慢启动还是拥塞控制。当cwnd<ssthresh,使用慢启动算法;当cwnd>ssthresh,使用拥塞避免算法;两者相等时任何一种都可以使用。慢启动阙值不是固定的,它会记住上一次“最好的”操作窗口估计值,即记录TCP最优窗口估计值的下界。

                                                          ssthresh = max(在外数据值/2, 2*SMSS)

       新的实现中,公式变为:ssthresh = max(min(cwnd, awnd)/2, 2*SMSS)

拥塞避免

       在慢启动阶段,cwnd会快速增长以帮助TCP确定一个慢启动阙值(Slow Start Threshold),即ssthresh。一旦达到阙值,为了更精细地确认网络传输能力上限,得到更多的传输资源而不致影响其他连接传输,将会启动拥塞避免算法。在拥塞避免阶段,cwnd的增长值近似于成功传输的数据段大小,这种近似的随时间线性增长的方式与慢启动的指数增长相比缓慢许多。

       拥塞避免算法假设由比特错误导致丢包的概率很小(远小于1%),因此有丢包发生就认为从发送方到接收方的传输路径中必然有某处出现了拥塞。

       在拥塞避免阶段,如果出现了丢包,假设丢包原因为超时,cwnd的值将被设为上一个ssthresh(大多数情况下,超时仍是引发慢启动的主要原因),重新进入慢开始过程。有的版本则直接将cwnd恢复为初始值,这对于有较大BDP的链路来说会使得带宽利用率低下。

       若收到重复ACK的数量超过其阙值dupthresh(或其他表明需要快速重传的信号)时,将会执行快速重传和快速恢复算法。

快速恢复

       在启动快速恢复后,cwnd的值将设为ssthresh+3*SMSS,每接收一个重复ACK,cwnd值暂时增加1SMSS,当接收到一个好的ACK时,则将cwnd重设为ssthresh。

       Reno版本的TCP拥塞控制完整过程如下图所示:

TCP拥塞控制

 

                                                                   本文部分内容摘自《TCP/IP详解 卷1:协议(中文版)第2版》,有改动