这一次彻底搞懂拥塞控制
在计算机网络当中,我们会反复听到过一个名词-拥塞控制。那么到底什么是网络拥塞?有那些拥塞控制方法?读完这篇文章,希望能让你有一个大概的了解。
网络拥塞的概念
先引一段百度百科对于网络拥塞的解释:
网络拥塞(congestion)是指在分组交换网络中传送分组的数目太多时,由于存储转发节点的资源有限而造成网络传输性能下降的情况。当网络发生拥塞时,一般会出现数据丢失,时延增加,吞吐量下降,严重时甚至会导致“拥塞崩溃”(congestion collapse)。通常情况下,当网络中负载过度增加致使网络性能下降时,就会发生网络拥塞。下图则描述了在有无拥塞控制的干预下,网络吞吐量随输入负载的增加的变化情况。
通过以上的描述,我们大概可以得到以下信息:
- 网络拥塞往往是由于对资源的请求超出了存储转发节点的能力而导致的。
- 网络拥塞可能会导致数据丢失,时延增加,吞吐量下降等问题。
- 若出现拥塞而不进行控制,有可能会使整个网络情况恶化,甚至网络吞吐降为0。
- 网络的拥塞状况与当前网络负载是密切相关的。
拥塞控制算法
在描述拥塞控制算法之前,我想先和大家介绍以下拥塞控制算法和流量控制算法的区别。
异同点
流量控制和拥塞控制的最大异同点其实就是他们针对的对象和解决的问题不同。
首先对于流量控制而言,它所针对的对象是正在通信两个主机。通过滑动窗口的动态变化确保双方的接受能力能够与发送能力想匹配(接收方告知发送方自己的缓存大小,从此控制发送端发送窗口的大小,从而达到流量控制的目的—-接收方控制发送方),而不至于出现超出缓存,主动丢包的情况。(PS:【关键点】1.端到端通信。2.滑动窗口)
对于拥塞控制而言,需要解决的是一个全局性的问题,因为可能局部的网络拥塞最终会造成全网的数据交换阻塞,最终导致全网瘫痪,只能通过重启网络来解决。出现这种问题主要是因为对局部网络当中的资源的需求大于超出该存储转发节点的处理能力,导致该节点无法处理其他的存储转发请求。最终导致其他请求超时重发,由此可能导致有更多的数据被注入到网络当中最终造成网络瘫痪。因此,拥塞控制涉及到的是所有的主机,路由器以及降低网络性能相关的所有因素。(拥塞控制的对象是发送方,且它并不涉及通信双方缓存的大小。指的是某一源端数据流在一个RTT内最多发送的数据包数)
那么介绍完了流量控制和拥塞控制的不同点。接下来,我们需要介绍以下两个参数:
- 拥塞窗口cwnd
- 慢开始门限ssthresh
发送方需要维护一个叫做拥塞窗口cwnd的状态变量,其值取决于网络的拥塞程度并且会跟随网络的拥塞程度动态变化。拥塞窗口的维护原则:如果网络没有发生拥塞,拥塞窗口就会不断增大(具体如何增大与ssthresh有关);但只要网络一发生拥塞,这个窗口就会减小。而判断网络发生的依据就是:超时报文(没有按时收到回复的报文,需要超时重传)。
发送方窗口的上限值 = Min [ rwnd, cwnd ](PS:rwnd是接收窗口的大小)
ssthresh也是进行拥塞控制时需要维护的一个状态变量:
- 当cwnd < ssthresh时,使用***慢开始算法***
- 打cwnd >= ssthresh时,使用***拥塞避免算法***
慢开始
当主机开始发送数据时,如果一下子将所有数据注入到网络当中,有可能会引起网络的阻塞。这是因为在我们刚刚开始进行数据传输时,发送端并不清楚网络的实际负载情况。因此,在这种场景下最好的一种办法就是先探测一下当前的网络状况,然后根据情况,不断尝试将拥塞窗口增大。举个例子来讲就是,我们在行军打仗的时候,一般不会选择让大部队直接进入一片陌生的区域。而是会先派一部分侦查员去侦察,根据侦查员反馈的情况,在将部队慢慢的分批次进入。通常在刚刚开始发送报文段时,都会先把拥塞窗口cwnd设置为一个最大报文段(MSS)的值。每次收到一个对新的报文段的确认之后,拥塞窗口最多增加一个MSS的数值。
根据上图我们可以看出来,每经过一个传输轮次,拥塞窗口cwnd就会加倍(2的幂次倍数增加)。这里的传输轮次指的是一次报文的往返时间RTT,不过这里之所以指出是传输轮次,是为了强调:整个的传输过程是将cwnd中的数据全部发送出去,并收到了对已发送的最后一个字节的确认(代表之前发送的数据全部得到确认)。但是为了防止拥塞窗口增长的过大而造成网络拥塞,还需要通过ssthresh状态变量对其进行限制。即当cwnd > ssthresh时,会改用拥塞避免算法而停用慢开始算法。
拥塞避免
拥塞避免算法是为了减缓拥塞窗口的增大速度,以此控制数据的注入。即每经过一个传输轮次就把发送方的拥塞窗口cwnd加1,而不是加倍。这样拥塞窗口cwnd就会按照线性规律缓慢增长。
介绍完了慢开始算法和拥塞避免算法之后,我们来看一下它们是如何搭配使用的:无论是在慢开始阶段还是拥塞避免阶段,只要发送方判断网络拥塞(这里的判断条件是发送方在指定时间内没有收到确认报文—判断已经发生超时),就要把ssthresh设置为当前发生拥塞时cwnd的一半,然后把拥塞窗口cwnd重新设置为1,执行慢开始算法。这样做的目的就是为了迅速减少主机发送到网络中的数据,使得发生拥塞的路由器有足够的时间可以将自己的堆压分组处理完。
快速重传
快重传要求接收方在收到一个失序报文时立刻响应,而不能等到自己发送数据的时候才捎带确认(防止超时!!!)。按照快重传算法的规定,发送方只要一连收到三个对同一数据报文的重复ACK就应该立即重传对方没有收到过的报文段,而不必等待到重传计时器RTO超时(有时候并不是因为网络原因)。—-PS:使用快重传最主要的原因是:对于个别非网络原因丢失的报文,发送方不会出现超时重传,可以及早发现并立即重传,也就不会误认为网络发生了拥塞,通过快重传算法可以将网络的吞吐提高20%。
快恢复
在执行快重传算法时,发送方一旦收到3个重复的ACK,就知道现在只丢失了个别的数据报文。于是不启动慢开始算法(因为判断不是因为网络拥塞原因而丢失的报文,因为收到了ACK的回复)而是选择执行快恢复算法。快恢复算法的过程如下:
- 发送方将慢开始门限ssthresh值和拥塞窗口cwnd均降低为原先的一半。
- 执行拥塞避免算法。
接下来的一个例子将整个拥塞避免过程当中用到的四种算法都进行了展示,希望大家能够仔细将其看懂并且理解:
以上就是对TCP拥塞控制知识的总结,希望能够帮助大家。
本文转载自: 掘金