小议BBR算法
BBR全称Bottleneck Bandwidth and RTT,它是谷歌在2016年推出的全新的网络拥塞控制算法。要说明BBR算法,就不能不提TCP拥塞算法。
传统的TCP拥塞控制算法,是基于丢包反馈的协议。基于丢包反馈的协议是一种被动式的拥塞控制机制,其依据网络中的丢包事件来作网络拥塞判断。即使网络中的负载很高时,只要没有产生拥塞丢包,协议就不会主动下降本身的发送速度。
TCP在发送端维护一个拥塞窗口cwnd,经过cwnd来控制发送量。采用AIMD,就是加性递增和乘性递减的方式控制cwnd,在拥塞避免阶段加性增窗,发生丢包则乘性减窗。
这个拥塞控制算法的假定是丢包都是拥塞形成的。
TCP拥塞控制协议但愿最大程度的利用网络剩余带宽,提升吞吐量。然而,因为基于丢包反馈协议在网络近饱和状态下所表现出来的侵略性,一方面大大提升了网络的带宽利用率;但另外一方面,对于基于丢包反馈的拥塞控制协议来讲,大大提升网络利用率同时意味着下一次拥塞丢包事件为期不远了,因此这些协议在提升网络带宽利用率的同时也间接加大了网络的丢包率,形成整个网络的抖动性加重。
TCP拥塞控制算法的假定是丢包都是拥塞形成的,而事实上,丢包并不老是拥塞致使,丢包可能缘由是多方面,好比:路由器策略致使的丢包,WIFI信号干扰致使的错误包,信号的信噪比(SNR)的影响等等。这些丢包并非网络拥塞形成的,可是却会形成TCP 控制算法的大幅波动,即便在网络带宽很好的状况下,仍然会出现发送速率上不去的状况。好比长肥管道,带宽很高,RTT很大。管道中随机丢包的可能性很大,这就会形成TCP的发送速度起不来。web
Google 的BBR出现很好的解决了这个问题。BBR是一种基于带宽和延迟反馈的拥塞控制算法。它是一个典型的封闭反馈系统,发送多少报文和用多快的速度发送这些报文都是每次反馈中不断调节。
BBR算法的核心就是找到两个参数,最大带宽和最小延时。最大带宽和最小延时的乘积就是BDP(Bandwidth Delay Product), BDP就是网络链路中能够存放数据的最大容量。知道了BDP就能够解决应该发送多少数据的问题,而网络最大带宽能够解决用多大速度发送的问题。若是网络比做一条高速公路,把数据比做汽车,最大带宽就是每分钟容许通行的汽车数量,最小RTT就是没有拥堵状况下,汽车跑一个来回须要的时间,而BDP就是在这条路上排满汽车的数量。算法
BBR如何探测最大带宽和最小延时
BBR是如何探测最大带宽和最小延时呢?首先有一点就是最大带宽和最小延时是没法同时获得的。segmentfault
如图所示,横轴是网络链路中的数据量,纵轴分别是RTT和带宽。能够发如今RTT不变的时候,带宽一直在上升,没有达到最大,由于这个时候网络没有拥塞,而带宽中止上涨的时候RTT持续变大,一直到发生丢包。由于这个时候,网络开始拥塞,报文累积在路由器的buffer中,这样延时持续变大,而带宽不会变大。图中BDP的竖线所标识的就是理想状况下最大带宽和最小延时。很明显,要找到BDP, 很难在同一时刻找到最小的RTT和最大带宽。这样最小RTT和最大带宽必须分别探测。
探测最大带宽的方法就是尽可能多发数据,把网络中的buffer占满,带宽在一段时间内不会增长,这样能够获得此时的最大带宽。
探测最小RTT的方法就是尽可能把buffer腾空,让数据交付延时尽可能低。
由此,BBR就引入了基于不一样探测阶段的状态机。数组
状态机分为4个阶段,Startup,Drain,ProbeBW, ProbeRTT。
Startup相似于普通拥塞控制里的慢启动,增益系数是 2ln2,每个来回都以这个系数增大发包速率,估测到带宽满了就进入 Drain状态,连续三个来回,测得的最大瓶颈带宽没有比上一轮增大 25%以上,就算带宽满了。
进入 Drain状态,增益系数小于 1,也就降速了。一个包来回,把 Startup状态中产生的拍队排空,怎样才算队列空了?发出去尚未 ACK 的数据包量 inflight,与 BDP 进行比较,inflight < BDP 说明空了,道路不那么满了,若是 inflght > BDP 说明还不能到下一个状态,继续 Drain。
ProbeBW是稳定状态,这时已经测出来一个最大瓶颈带宽,并且尽可能不会产生排队现象。以后的每一个来回,在 ProbeBW状态循环(除非要进入下面提到的 ProbeRTT状态),轮询下面这些增益系数,[5/4, 3/4, 1, 1, 1, 1, 1, 1],如此,最大瓶颈带宽就会在其中止增加的地方上下徘徊。大部分时间都应该处于 ProbeBW状态。
前面三种状态,均可能进入 ProbeRTT状态。超过十秒没有估测到更小的 RTT 值,这时进入 ProbeRTT状态,把发包量下降,空出道路来比较准确得测一个 RTT 值,至少 200ms 或一个包的来回以后退出这个状态。检查带宽是不是满的,进入不一样的状态:若是不满,进入 Startup状态,若是满,进入 ProbeBW状态。
BBR算法不会由于一次或者偶然的丢包就大幅下降吞吐量,这样就比TCP就有较强的抗丢包能力。网络
如图所示,cubic在丢包率上升的时候,吞吐量降低很快。而BBR在5%以上的丢包才会出现明显的吞吐量降低。
BBR与基于丢包反馈的cubic和基于延时反馈的vegas算法的本质区别在于,BBR无视随机丢包,无视时延短暂波动,采用了实时采集并保留时间窗口的策略,保持对可用带宽的准确探知。事实上,丢包并不必定会形成带宽减小,延迟增长也不必定会形成带宽减小,cubic没法判断是否拥塞形成的丢包,vegas对延时增长过于敏感,会致使竞争性不足。
BBR能够区分出噪声丢包和拥塞丢包,这样意味着,BBR比传统TCP拥塞控制算法具备更好的抗丢包能力。架构
BBR在实时音视频领域的应用
实时音视频系统要求低延时,流畅性好,而实际网络状态倒是复杂多变的,丢包,延时和网络带宽都在时刻变化,这就对网络拥塞控制算法提出了很高的要求。它须要一种带宽估计准确,抗丢包和抖动能力好的拥塞控制算法。
目前Google的webrtc提供了GCC控制算法,它是一种发送侧基于延迟和丢包的控制算法,这个算法的原理在不少地方都有详细描述,这里再也不赘述。GCC用于实音视频的主要问题还在于在带宽发生变化时,它的带宽跟踪时间比较长,这样就会形成带宽突变的时候没法及时准确探测带宽,可能形成音视频卡顿。
既然BBR有良好的抗丢包能力,天然也被想到应用到实时音视频领域。可是,BBR并非为处理实时音视频设计的,因此须要对一些问题作一些优化。
第一,BBR在丢包率达到25%以上,吞吐量会断崖式降低。
这是由BBR算法的pacing_gain数组[5/4, 3/4, 1, 1, 1, 1, 1, 1]的固定参数决定的。
在pacing_gain数组中,其增益周期的倍数为5/4,增益也就是25%,能够简单理解为,在增益周期,BBR能够多发送25%的数据。
在增益期,丢包率是否抵消了增益比25%?也就是说,x是否大于25。
假设丢包率固定为25%,那么,在增益周期,25%的增益彻底被25%的丢包所抵消,至关于没有收益,接下来到了排空周期,因为丢包率不变,又会减小了25%的发送数据,同时丢包率依然是25%...再接下来的6个RTT,持续保持25%的丢包率,而发送率却仅仅基于反馈,即每次递减25%,咱们能够看到,在pacing_gain标识的全部8周期,数据的发送量是只减不增的,而且会一直持续下去,这样就会断崖式下跌。
怎样才能对抗丢包,这就须要在每一个周期考虑丢包率,把丢包率补偿进去。好比丢包率达到25%的时候,增益系数就变成50%,这样就能够避免因为丢包带来的反馈减损,然而,你又如何判断这些丢包是噪声丢包仍是拥塞丢包呢?答案在于RTT,只要时间窗口内的RTT不增长,那么丢包就不是拥塞致使的。
第二,BBR的最小RTT有个10s超时时间,在10s超时后,进入ProbeRTT 状态,并持续最小200ms,此状态下,为了排空拥塞,inflight只容许有4个包,这会致使音视频数据在这段时间内堆积在发送队列中,使得时延增长。
可行的解决办法是,再也不保留ProbeRTT状态,采用多轮降低的方式排空拥塞,而后采样最小RTT,也就是在infight > bdp的时候,设置pacing gain为0.75,用0.75倍带宽做为发送速率,持续多轮,直到inflight < bdp, 此外,最小RTT的超时时间改为2.5s,也就是说不采用很是激进的探测方式,避免了发送速率的大幅波动,能够改善探测新的带宽过程当中发送队列中产生的延时。
第三,开始提到pacing gain数组上探周期为1.25倍带宽,随后是0.75倍带宽周期,这两个RTT周期之间会出现发送速率的剧烈降低,这可能会使音视频数据滞留在buffer中发不出去,引入没必要要的延时。
解决办法能够考虑减少上探周期和排空周期的幅度,好比使用[1.1 0.9 1 1 1 1 1 1]这种pacing gain参数,这样作的优势就是能够保证媒体流的平稳发送,发送速率不会大幅波动,缺点是,网络带宽改善的时候,上探时间会变长。
第四,BBR探测新带宽收敛慢的问题
原始的BBR算法的收敛性受到pacing gain周期影响,带宽突降的时候,BBR须要多个轮次才会降到实际带宽。这是因为BBR每轮只能降速一次,而pacing gain的6个RTT的保持周期大大加长了这个时间。解决的办法就是随机化pacing gain的6个保持周期,若是是0.75倍周期,就一次降速到位,这样能够极大的减小BBR的收敛时间。
最后,BBR算法看似简单,可是应用到实时音视频却没有那么简单,须要大量的实验优化,谷歌也在webrtc中引入BBR,目前仍在测试中。本文提到的改进方法是网易云信在这方面的一些尝试,但愿可以抛砖引玉,有更多有兴趣的人可以为BBR应用到实时音视频领域出力。测试