前两篇文章,我零零散散地介绍了关于本地队列和中间队列的一些管理机制和算法:
《TCP BBR算法中Pacing,cwnd,fq以及TSQ对RTT的影响》
《TSQ/CoDel队列管理以及TCP BBR如何解决Bufferbloat问题》
然而这太零散了,如果你想将所有这一切融合在一个统一的框架中,会发现在它们之上的层次上还有很多工作要做。本文为了这个目的写出,给出一个提纲挈领。顺便感谢一下与我讨论拥塞临界点的那位研究生朋友,不然我还没想到要写这篇文章,万分感谢。
膝点和崖点
在一个排队系统中,有两个临界点,将该排队系统分割成了三个状态:
而上图中的队列长度如果分布在一个连续的时间维度,便是到达率了,在一个典型的排队系统中,到达率符合泊松分布。
排队论的结论
上一节描述了膝点和崖点的特性并且定义了它们,我们来看看算出它们的值,这就需要排队论的知识。本文并不推导这些结论,而是直接使用。
N:队列长度
T:排队延时
a:泊松分布的到达率
b:固定服务率
- 一个排队系统的队列长度
- 一个排队系统的排队时延
可见,要想不拥塞,服务率要大于到达率的期望值…当到达率和服务率之比等于1/2的时候,系统从完全不排队开始排队,当该比值为1的时候,队列趋向于无穷大,因此我们按照这个理论重新定义膝点和崖点:
体现在坐标系里就是:
队列管理和拥塞控制的位置
知道了那么一大堆理论,有何用呢?
现在问题来了,如何来做拥塞控制?
手里有一把钉子,有一把锁,眼前有个门要装锁,随之的问题就是把锁装在哪个位置。要给出一个拥塞控制机制,问题是一样的,要在哪个位置做拥塞控制呢?
根据上述的排队系统模型,有两个地方可以做拥塞控制,装上这把锁。一个位置是膝点,一个位置是崖点。哪个位置是正确的位置呢?其实这代表了两种不同的理念,本身都是无可厚非的,在膝点做拥塞控制的理念在于从根本上避免排队,从而避免拥塞,而在崖点做拥塞控制的理念则在于直接控制队列长度从而避免拥塞,孰是孰非,现实生活中均有各自的例子,存在即是合理的,因此都对。
现实中的例子
膝点拥塞控制的例子
高速公路与互通立交
高速公路通过一个全程恒定的限速来避免排队现象,而互通立交则通过四向匝道来复用时间,到达交叉路口的同时四向通行,避免排队现象。
CoDel队列管理
CoDel限制最大排队时间以及最长容忍时间来避免排队现象。为什么容忍时间段是一个合理的概念,请参见圣经《新约•马太福音》里那个打脸名句。
BBR拥塞控制算法
BBR监控最大的采集带宽以及最小RTT来探测排队并主动避免之。BBR使用的时间窗口概念迎合了CoDel的容忍时间段概念。
崖点拥塞控制的例子
红绿灯
在普通道路的交叉路口,采用时延较大的红绿灯来复用时间,这必然会造成两个方向的被动排队,然而这是另外两个方向通行所必须的,红绿灯的切换间隔控制了队列长度。
高速公路收费站
由于万恶的高速公路收费制度,收费站工作人员的收费延时必然造成收费站口的排队现象,然而队列长度有个红线(不知你是否注意),队列超过此红线则免费放行。
RED队列管理
传统的路由器交换机,由于摩尔定律造成存储设备越发便宜从而队列缓存的增加,为了充分利用它们(不然没有购置的必要便无人买单),RED在最大可接受的队列长度内限制了队列长度的阈值。
Reno/CUBIC拥塞控制算法
这看起来完全是迎合了RED AQM机制的,然而早期的设计动机却不是这样,那时路由器的队列都比较短(存储设备太贵!),早期的动机是在迎合一个数学上收敛的AIMD控制论模型,最终偏偏不偏不倚地正中了AI排队,MD清空这么一个同步过程。
Why?
我发现,凡是在膝点做拥塞控制的,大部分是高速环境,而在崖点做拥塞控制的,则是相对低速的环境,这是为什么呢?
当然,我的结论并不一定正确,但是在我的这个观察结论中,理由很简单,因为在高速环境中,从膝点到崖点的时间非常短,可能来不及拥塞控制机制的反应,在一个负反馈系统中,信号从感受器到效应器总是会有滞后性的,这个滞后的延时一般会大于等于从膝点到崖点的过渡延时,所以会造成拥塞的代价非常大。
而在一个低速的环境中,只需要依照标准控制论中的收敛模型进行负反馈即可,反馈的滞后时间远小于从膝点到崖点(即从排队到拥塞)的过渡时间。
总结一下
可见,拥塞控制离不开两个理论,一个是排队理论,一个是控制理论。