TCP BBR简介

4,615 阅读6分钟

前言

TCP BBR是由来自Google的 Neal Cardwell 和 Yuchung Cheng 发表的新的TCP拥塞控制算法,目前已经在Google内部大范围使用并且随着linux 4.9版本正式发布。不过我个人第一次接触到BBR却是在搭建上网工具的时候,个人体感开启了BBR之后的访问速度明显提高,在这里主要总结一下从网上了解到的相关知识。

BBR简介

BBR的名称实际上是bottleneck bandwith and round-trip propagation time的首字母缩写,表明了BBR的主要运行机制:通过检测带宽和RTT这两个指标来进行拥塞控制。 BBR算法的主要特点有以下几个:

  1. BBR不考虑丢包,因为丢包(在现在这个时代)并不一定是网络出现拥塞的标志了
  2. BBR依赖实时检测的带宽和RTT来决定拥塞窗口的大小:窗口大小 = 带宽 * RTT

丢包不一定等于发生拥塞

在1988发表的论文《Congestion Avoidance and Control》中,Van Jacobson就提出丢包可以作为发生拥塞的信号,在当时的硬件性能下这个推论是成立的,后续的诸多拥塞控制算法也都是按照这个思路来实现(当然也有例外比如Vegas和Westwood),而如今网卡带宽已经从Mbps增长到了Gbps,丢包与拥塞这两者之间的关联关系也就变得微弱了。

在现在网络状况下,丢包可能是由于拥塞,也有可能是因为错误。在数据中心内部,错误丢包率并不高(约在十万分之一);而在广域网上错误丢包率则高得多。更重要的是,在有一定错误丢包率的长肥管道(带宽大、延时高的网络)中,传统的拥塞控制算法会将发送速率收敛到一个比较小的值,导致网络利用率非常低。

另外,网络链路中很多设备都会有缓冲,用于吸收网络中的波动,提高转发成功率,而传统的基于丢包的拥塞控制算法感知到丢包时,这些缓冲却早已被填满了,这个问题成为bufferbloat(缓冲区膨胀)。而bufferbloat带来的影响主要有两个:

  1. 延时会增加,同时缓冲越大延时增加得越多
  2. 共享网络瓶颈的连接较多时,可能会因为缓冲区被填满而发生丢包。但这种丢包并不意味着发生了拥塞

总结一句话,时代已经变了,丢包不一定等于拥塞了。

基于带宽和RTT决定拥塞窗口

BBR既然不把丢包作为拥塞出现的信号,就需要找到其他机制来检测拥塞是否出现。Vegas算法基于时延来判断是否出现了拥塞,Westwood算法基于带宽和RTT来决定拥塞窗口的大小,但是受限于linux拥塞控制实现的原因,Westwood计算带宽和RTT的方式十分粗糙。BBR也采用了和Westwood一样的方式,但是它的作者同时改进了linux拥塞控制的实现,使得BBR能够得到更完全的控制。

一个网路链路能够传输的最大吞吐取决于这条网路链路上的物理时延(Round-Trip Propagation Time,在BBR中简写为RTprop)与链路上速度最低的一段的带宽(Bottle-neck Bandwidth,在BBR中简写为BtlBw)的乘积。这个乘积叫做BDP(Bottle-neck Bandwidth Delay Production),即BDP=BltBw x RTprop,也就是将链路填满数据同时不填充中间链路设备缓冲的最大数据量。BBR追求的就是数据发送速率达到BDP这个最优点。

带宽与RTT的测不准原理

在一条网络链路上,RTprop和BtlBw实际上是互相独立的两个变量,它们都可能在对方不变的情况下增大或者减小。而要精确地测得延时的最小值,就必须保证网络设备的缓冲为空,链路上的流量越少越好,但此时的带宽就低;要测得带宽的最大值,就必须发送尽可能多的数据来把网络带宽填满,缓冲区就会有部分数据,延时就会上升;这就有点类似物理学中的不确定性原理。

而BBR对于这个问题的解决方式就是取一定时间范围内的RTprop极小值与BtlBw极大值作为估计值。

BBR算法的各个阶段

在连接建立的时候,BBR也采用类似慢启动的方式逐步增加发送速率,然后根据收到的ack计算BDP,当发现BDP不再增长时,就进入拥塞避免阶段(这个过程完全不管有没有丢包)。在慢启动的过程中,由于几乎不会填充中间设备的缓冲区,这过程中的延迟的最小值就是最初估计的最小延迟;而慢启动结束时的最大带宽就是最初的估计的最大延迟。

慢启动结束之后,为了把慢启动过程中可能填充到缓冲区中的数据排空,BBR会进入排空阶段,这期间会降低发送速率,如果缓冲区中有数据,降低发送速率就会使延时下降(缓冲区逐渐被清空),直到延时不再下降。

排空阶段结束后,进入稳定状态,这个阶段会交替探测带宽和延迟。带宽探测阶段是一个正反馈系统:定期尝试增加发包速率,如果收到确认的速率也增加了,就进一步增加发包速率。具体来说,以每8个RTT为周期,在第一个RTT中,尝试以估计带宽的5/4的速度发送数据,第二个RTT中,为了把前一个RTT多发出来的包排空,以估计带宽的3/4的速度发送数据。剩下6个RTT里,使用估计的带宽发包(估计带宽可能在前面的过程中更新)。 这个机制使得BBR在带宽增加时能够迅速提高发送速率,而在带宽下降时则需要一定的时间才能降低到稳定的水平。

除了带宽检测,BBR还会进行最小延时的检测。每过10s,如果最小RTT没有改变(也就是没有发现一个更低的延迟),就进入延迟探测阶段。延迟探测阶段持续的时间仅为 200 毫秒(或一个往返延迟,如果后者更大),这段时间里发送窗口固定为4个包,也就是几乎不发包。这段时间内测得的最小延迟作为新的延迟估计。也就是说,大约有2%的时间BBR会用极低的发包速率来测量延迟。

总结

这次主要总结了BBR的特点以及各个阶段,但是BBR并非就是完美的横扫一切的拥塞控制算法,它需要和实际的场景相结合才能发挥威力,后续再继续深入了解了。