Linux Kernel 4.9 中的 BBR 算法与之前的 TCP 拥塞控制相比有什么优势?

关注者
3123
被浏览
198650
@李博杰的回答,写得很棒,已经回答得很详细了,我也来粗略说一下我的理解,有不妥之处还请指出。
我自己对BBR的总结就是:终于转变了对“拥塞“这个概念的理解,经典的拥塞控制算法比如reno/newReno/Cubic无一例外都是将丢包作为拥塞的信号,然后降低发送速率。而在该算法中,不考虑丢包,而是基于这样一个定义:当网络上的包数大于BDP(带宽时延乘积)时,就认为出现了拥塞。所以重点就在于如何准确地测量出瓶颈链路的带宽和整个链路的传播时延。
在1980年设计拥塞控制算法的时候,将拥塞等同于丢包没有很大问题的,当时路由器的缓存小,链路带宽也不高。但是现在,路由器的缓存已经很大了,基于丢包的拥塞算法会一直增加窗口,直至把瓶颈路径上的路由缓存填满,然后出现丢包。但是,在这个过程中时延已经增大到我们无法容忍的程度了,所以需要反思这种基于丢包的拥塞控制思想。
因为网络对TCP连接的两端来说是一个黑盒,没有明显的信息告诉我们说网络出现了拥塞(支持ECN的路由设备在现网中的普及率不高 ),所以我们只能通过反馈来推测的,这也就是为啥需要拥塞控制算法的原因之一了。
这个算法的实现也有一个重大的思路转变,那就是不能仅仅只控制发多少包,也就是用拥塞窗口cwnd和慢启动门限值ssthresh来控制发包的多少,我们还应该控制发包的速率,所以pacing_rate成为主要控制因素。
另外,这篇论文的出现也印证了我们的一个思路是可行的:丢包恢复和窗口管理解耦。如果我们发现有丢包,重传就好了嘛,至于发送速率如何调整,全部交给拥塞控制算法就好了。

这里回答一下 @行功的几个问题。
2. BBR的“测不准”是个什么鬼?
这里指的是RTprop和BtlBW不能同时测得。
RTprop指的是链路的传播时延,也就是等于路径长度 / 信号传播速率,只有在链路上没有任何排队和其他时延的时候,才能有RTT来近似。因此, inflight(在途数据包数)要小于BDP。而BtlBW是瓶颈链路的带宽,只有当发的包数>= BDP时,才能用发送速率来近似。因此这个两个值不能同时得到。从这幅图可以很清楚地看出,RTprop是当amout inflight < 最优点测得;BtlBw是 amout inflight > 最优点测得。
3. BBR号称的primary control的探测带宽有用么?
首先我们要知道对于一条连接来说,它的可用带宽是什么,当它独占整个链路时,它的可用带宽就近似为链路的物理带宽,但多条流共享链路时,最理想最公平的肯定是BW/n。但是这个我们并不知道,只能通过一点一点地发包探测,比如可以先发快一点,发现出现拥塞了就发慢一点,这样反复探测直到收敛。就如下图所示:
4. BBR到底是什么?
“BBR真正起作用是它放第二位的CWND=bw*PropRTT控制。“
这句话我不敢苟同。因为在论文中说的以pacing_rate作为主要控制手段。在内核代码中我们可以看到sock结构体中有一个域是sk_pacing_rate。
同时我们也看到tcp_bbr.c里有这么一段注释:
* NOTE: BBR *must* be used with the fq qdisc ("man tc-fq") with pacing enabled,
* since pacing is integral to the BBR design and implementation.
* BBR without pacing would not function properly, and may incur unnecessary
* high packet loss rates.
*/
并参考该链接:TSO sizing and the FQ scheduler里有这么一句话:
That transmission time is used to implement the TCP pacing support. If a given socket has a pace specified for it, FQ will calculate how far the packets should be spaced in time to conform to that pace.
所以我个人目前理解的是pacing是通过将sock中的sk_pacing_rate传递给FQ scheduler来实现的。由于我没有完全跟过这个代码实现的全过程,所以不能完全肯定pacing是如何具体实现的。但是可以看出用pacing来控制发包速率是完全可行的。