TCP BBR v2

4,187 阅读4分钟

前言

上次简单介绍了BBR的特点和基本的实现思路,但是BBR并不就是完美的吊打一切其他算法的存在。在2018年7月的时候google发布了BBR的相关改进的计划,目前已经有BBR v2 alpha版本的试用文档,正式版尚未发布。所以借助BBR v2的更新内容简单总结一下BBR的一些不足或者缺点。

BBR v2的计划更新内容

  • 改进与其他算法共存时的公平性:调整BBR探测带宽时的时间来和CUBIC/Reno共存
  • 降低排队压力(丢包和排队延时),在计算以下指标时将丢包和ECN考虑在内
    • in-flight 数据的安全范围
    • 退出STARTUP的时机
  • 加快min_rtt的收敛:增加PROBE_RTT的频率
  • 降低PROBE_RTT时的极端性

计算in-flight数据大小的新模型

v2版本使用新的模型来计算in-flight数据的大小范围,其中包含三个参数:inflight_lo、inflight_high、inflight_prob。

  • inflight_lo:基于丢包和ECN信号计算出来的in-flight数据包最小值
  • inflight_hi:出现丢包和ECN信号前的in-flight数据包最大值
  • inflight_prob:探测带宽时超过inflight_hi的增量

STARTUP阶段

BBR v1中,STARTUP会持续增加发送速度,直到探测到的最大带宽趋于平稳然后退出。但是这个阶段并不会把丢包考虑在内,所以在STARTUP阶段可能会出现丢包严重的现象。v2版本中在STARTUP阶段的退出条件中增加了一项:当发现丢包或者ECN时,也会提前退出STARTUP阶段,同时更新inflight_hi变量。STARTUP阶段模式的另一个修改是将拥塞窗口增益由2.89改为2,这个改动反而会加重因为ACK聚合而导致失速问题,而BBR对此的解决方案则是BBR Extra-CWND,这里还没有太弄明白,后续再详细了解下。

DRAIN阶段

DRAIN阶段会降低发送速度,尝试清空中间设备的缓存,直到inflight数据少于预估的带宽("drain to target")。这个阶段并没有改动。

PROBE_BW阶段

v2版本中PROBE_BW分为三个阶段:cruise(平稳)、up(探测更多带宽)和down(收敛到可用带宽)。同时为了与其他基于丢包的算法共存,PROBE_BW周期的时长不再是8个min_rtt,而是min(T_bbr, T_reno),T_bbr是时间范围为2-5s,T_reno是min(BDP, 50)* RTT。BDP过期时间不在是过去的十轮,而是更长的2个PROBE_BW周期时长。

cruise

v1版本中平稳阶段会使inflight保持在一个恒定的值,而v2版本则会预留一部分空间(让给其他连接),使inflight在inflight_lo和inflight_hi之间,并且会根据丢包和ECN事件减小inflight_lo的值。

up

v1版本中在探测更多带宽时简单地增加1/4的发送速度,而v2版本中采用了指数增长的方式,先慢后快地探测可用带宽,直到出现丢包或者新的可用带宽大于预估带宽的1.25倍,同时会在出现丢包时更新inflight_hi。

down

v1版本中每次收敛只会降低1/4,而v2版本中则直接采用了"drain to target"的策略,会直接收敛到预估带宽。后续这个阶段可能会直接代替DRAIN阶段。

PROBE_RTT阶段

v1版本中,在进入PROBE_RTT阶段时,为了探测min_RTT会直接将窗口降到4个,同时为了尽量减小PROBE_RTT带来的吞吐降低的影响,PROBE_RTT的频率比较低(10s一次)。这就使得BBR在收敛时的速度很慢(通常需要20~30s)。v2版本中对此作了两点改进:

  • 窗口降低的更温和,不再是4而是0.75*BDP
  • 探测得更频繁,不再是10s一次而是2.5s一次

通过这样的调整,使得PROBE_RTT不再那么激进,也可以有效提高收敛的速度。

总结

BBR v2版本总的来说更加保守了,把丢包和ECN加入了考虑范围,同时还考虑到与其他算法共存时的情况。

附:ECN即显式拥塞通知(Explicit Congestion Notification),它可以通过显式的通知来告知网络两端发生了拥塞。具体可以参考维基百科。