分享一下我老师大神的人工智能教程!零基础,通俗易懂!http://blog.youkuaiyun.com/jiangjunshow
也欢迎大家转载本篇文章。分享知识,造福人民,实现我们中华民族伟大复兴!
本文试图给出一些与BBR算法相关但却是其之外的东西。
1.TCP拥塞的本质
注意,我并没有把题目定义成网络拥塞的本质,不然又要扯泊松到达和排队论了。事实上,TCP拥塞的本质要好理解的多!TCP拥塞绝大部分是由于其”加性增,乘性减“的特性造成的!也就是说,是TCP自己造成了拥塞!TCP加性增乘性减的特性引发了丢包,而丢包的拥塞误判带来了巨大的代价,这在深队列+AQM情形下尤其明显。
我尽可能快的解释。争取用一个简单的数学推导过程和一张图搞定。
除非TCP端节点之间的网络带宽是均匀点对点的,否则就必然要存在第二类缓存。TCP并无法直接识别这种第二类缓存。正是这第二类缓存的存在导致了拥塞的代价特别严重。我依然用经典的图作为基准来解释:
假设TCP端节点之间的BDP为C,那么:
C = C1 + C2 (其中C1是网络本身的管道容量,而C2是节点缓存的容量)
由于路径中最小带宽为B,那么整个链路的带宽将由B决定,在排队未发生时(即没有发生拥塞时),假设测量RTT为rtt0,发送速率为B0=B,则:
C1 = B0*rtt0
C = B0*rtt0 +C2 > B*rtt0
此时,任何事情均为发生,一切平安无事!继续着TCP”加性增“的行为,此时发送端继续线性增加发送速率,到达B1,此时:
B0*rtt0 < B1*rtt1
C是客观的不变量,这会导致C2开始被填充,即开始轻微排队。排队会造成RTT的增加。假设C2已经被加性增特性填充到满载的临界,此时发送带宽为B2,即:
C = B2*rtt2 = B*rtt0 + C2
B2*rtt2是定值,rtt2在增大,B2则必须减小!但是”临界值已经达到“这件事反馈到发送端,至少要经过1/2个RTT,在忽略延迟ACK和ACK丢失等反馈失灵情形下,最多的反馈时间要1个RTT。问题是,TCP发送端怎么知道C2已经被填满了??它不知道!除非再增加一些窗口,多发一个数据包!这行为是如此的小心翼翼,以至于你会认为这是多么正确的做法!在发送端不知情的情况下,会持续增加或者保持当前的拥塞窗口,但是绝对不会降低,然而此时RTT已经增大,必须降速了!事实上,在丢包事件发生前,TCP是一定会加性增窗的,也就是说,丢包是TCP唯一可以识别的事件!
TCP在临界点的加性增窗行为,目的只是为了探测C2是不是已经被填满。我们来根据以上的推导计算一下这次探测所要付出的代价。由于反馈C2已满的时间是1/2个RTT到1个RTT,取决于C2的位置,那么将会在1/2个RTT到1个RTT的时间内面临着丢包!注意,这里的代价随着C2的增加而增加,因为C2越大,RTT的最终测量值,即rtt2则越大!这就是深队列丢包探测的问题。然而,在30多年前,正是这个”加性增“行为,直接导出了”基于丢包的拥塞控制算法“。那时没有深队列,问题貌似还不严重。但随着C2的增加,问题就越来越严重了,RTT的增大使得丢包处理的代价更大!
记住,对丢包的敏感不是错误,基于丢包的拥塞探测的算法就是这样运作的,错误之处在于,丢包的代价太大-窗口猛降,造成管道被清空。这是由于深队列的BufferBloat引发的问题,在浅队列中问题并不严重。随着路由器AQM技术的发展,好的初衷会对基于丢包的拥塞探测产生反而坏的影响。
现在,我们明白了,之所以基于丢包的拥塞控制算法的带宽利用率低,就是由于其填充第二类缓存所平添排队延迟造成的虚假且逐渐增大的RTT最终导致了BDP很大的假象,而这一切的目的,却仅仅是为了探测丢包,自以为在丢包前已经100%的利用了带宽,然而在丢包后,所有的一切都加倍还了回去!是丢包导致了带宽利用率的下降,而不是增加!!
总结一句, 用第二类缓存来探测BDP是一种透支资源的行为。
我一直觉得这不是TCP的错,但在发现BBR是如此简单之后,不再这么认为了,事实上,通过探测时间窗口内的最大带宽和最小RTT,就可以明确知道是不是已经填满了第一类缓存,并停止继续填充第二类缓存,即向最小化排队的方向收敛!曾经的基于时延的算法,比如Vegas,其实已经在走这条路了,它已经知道RTT的增加意味着排队了,只是它没有采用时间窗口过滤掉常规波动,而是采用了RTT增量窗口来过滤波动,最终甚至由于RTT抖动主动减少窗口,所以会造成竞争性不足。不管怎样,这是一种君子行为,它总是无力对抗基于丢包算法的流氓行为。
&n