[转帖]理解 BBR 拥塞控制算法--理论篇

理解,bbr,拥塞,控制算法,理论 · 浏览次数 : 0

小编点评

**BBR (Bottleneck Bandwidth and Round-trip propagation time) 是一个用于拥塞控制的算法,它比 CUBIC 等传统的拥塞控制算法性能更出色。** **主要特点:** * 提前控制发送速度,避免在丢包率达到最大时进行暴力限制。 * 使用 TCP pacing 进行发包控制,确保稳定发包速度。 * 周期性地探测链路条件,以优化发送速率。 * 使用增益循环控制发送速率,以应对网络变化。 **性能结果:** BBR 在一些丢包率的环境下,性能大幅度超过 CUBIC。例如,在 1% 的丢包率的情况下,BBR 的性能可比 CUBIC 的性能提高 3 倍。 **主要步骤:** 1. 确定链路带宽和往返时延。 2. 每个 RTT 的发送速率根据链路条件进行调整。 3. 随着 inflight 的增长,BBR 计算发送速率并根据增益循环调整。 4. 确保每个报文都能在链路上得到及时处理。 **结论:** BBR 是一种高效的拥塞控制算法,特别适合在存在丢包率的弱网环境中使用。它可显著提高网络性能,降低丢包率。

正文

https://switch-router.gitee.io/blog/bbr1/

 

简介

BBR (Bottleneck Bandwidth and Round-trip propagation time)是 Google 在 2016 年发布的一套拥塞控制算法。它尤其适合在存在一定丢包率的弱网环境下使用,在这类环境下,BBR 的性能远超 CUBIC 等传统的拥塞控制算法。

以下是 Google 公开的的一些资料

paper

video

slides

github

本文将帮助你理解 BBR。

使用 BBR

没有比展示效果更适合作为开篇的了。

这里使用 iperf 来测试两个主机之间的 TCP 传输性能。tc 工具可以模拟传输时延和丢包率。

tc qdisc add dev eth0 root netem loss 1% latency 25ms

下面这是一些测试结果

可以看到,在存在丢包的场景下,BBR 的性能远远强于 CUBIC.

网络拥塞与控制

网络中的数通设备(交换机路由器)在入方向通常都会有缓存入报文的队列,其目的是为了应付短时间内涌入的大量报文。但如果入方向的报文持续超负荷,缓存队列也一定会被填满,此后的报文就只能被无情丢弃,之后发送端便能感知到报文丢了。

可以把网络链路想象为一根水管,路径上的数通设备会自带一个蓄水池,一般不会使用。而当水流变大时,蓄水池开始蓄水,如果超过蓄水极限,则水流会溢出(报文丢包)。

当发送端感知到丢包时,传统的 TCP 拥塞控制算法会减小发送端的拥塞窗口 Cwnd,限制报文的发送。这类拥塞控制算法也被称为基于丢包(Loss-based)的拥塞控制算法。

这显然不是最好的时机! 因为使用缓存队列并不能提升整个链路的带宽,反而还会增大报文的 RTT (每个报文的排队时间变长了)。缓存队列只是应急区域,平时是不应该被使用的。

BBR 的设计思路

控制时机提前,不再等到丢包时再进行暴力限制,而是控制稳定的发包速度,尽量榨干带宽,却又不让报文在中间设备的缓存队列上累积。

为了得到稳定的发包速度,BBR 使用 TCP Pacing 进行发包控制,因此 BBR 的实现也需要底层支持 TCP Pacing; 为了榨干带宽,BBR 会周期性地去探测是否链路条件变好了,如果是,则加大发送速率; 为了不让报文在中间设备的缓存队列上累积,BBR 会周期性地探测链路的最小 RTT,并使用该最小 RTT 计算发包速率。

BBR 理论基础

下图是来自 BBR paper 里的一张经典设计图

这张图分为上下两部分:上半部分的 Y 轴是 RTT,下半部分的 Y 轴则表示 delivery rate (也就是 estimated bandwidth)。特别注意的是 X 轴不是时间,而是 amount inflight,也就是在途报文的数量。

整个图从左到右可分为 3 个区域:1. app limited, 2. bandwidth limited, 3. buffer limited

    1. app limited

这个区域中,这条流上流量较小,没有充分利用信道,不存在阻塞的情况,delivery rate 线性增加,因此 RTT 保持不变,为链路的固有往返时延(RTprop)。

    1. bandwidth limited

这个区域表示 inflight 报文数量超过了 BDP,超过的部分是被中间设备缓存,最终表现出来就是 delivery rate 不变(只跟 bandwidth 有关),而 RTT 由于中间设备缓存 queue 的存在而线性增加。

    1. buffer limited

inflight 报文数量继续增加,超过 BDP 的部分最终也超过了中间设备的缓存极限,出现丢包。

BBR 追求的目标是保持 inflight 报文数量就为 BDP,这样既充分利用了 bandwidth,每个报文又能享受到 RTprop。

尽管 bandwith 和 RTT 都是可测量的,但很遗憾的是它们不能被同时探测!

BBR 采用的方案是分时探测,即在不同的状态下探测 bandwidth 和 RTT。

BBR 状态机

采用 BBR 进行拥塞控制的流在任一时刻都是处于以下四个状态之一:Startup、Drain、Probe Bandwidth 和 Probe RTT。其中 Probe Bandwidth 属于稳态,其他三个状态都是暂态。

下面四个状态的转移图:

              |
              V
     +---> STARTUP  ----+
     |        |         |
     |        V         |
     |      DRAIN   ----+
     |        |         |
     |        V         |
     +---> PROBE_BW ----+
     |      ^    |      |
     |      |    |      |
     |      +----+      |
     |                  |
     +---- PROBE_RTT <--+

Startup & Drain

Startup 是 BBR 控制的流启动时的状态,为了能尽快找到链路的瓶颈带宽 BtlBw,处于 Startup 状态的流每一个 RTT 会将报文发送速率会提高一倍。指数增长的发送速率使得 inflight 报文快速增加,也使得 delivery rate 快速增加,从而 BBR 计算的 bandwith 也快速增加。

随着 inflight 越过 BDP 这条线,delivery rate 不再变化,此时 BBR 测量到的 bandwidth 也会达到峰值。当 BBR 看到 测量到的 bandwidth 连续 3 个 RTT 不再显著增长时(增长幅度小于 25%),变会退出 Startup 状态,进入 Drain 状态。

Drain 状态的目标是让 inflight 报文数量回到 BDP 的水平,其存在的意义是为了抵消掉在 Startup 状态后期向网络灌入的超量报文。

随后,该流会进入 Probe Bandwidth 状态

Probe Bandwidth 状态

Probe Bandwidth 是四个状态中唯一的稳态,也是持续时间最长的状态 (大概 98% 的时间)。

在此状态下,BBR 会不断的去探测(或者说是压榨)带宽。

BBR 定义了一个增益循环(gain cycling)的概念,将增益系数作用到 pacing rate 上,以此控制报文发送速度。

具体的定义是,一个 cycle 包含 8 个 phase,每个 phase 的持续时间为 1 个 min RTT。8 个 phase 的 gain 分别为:1.25、0.75、1、1、1、1、1、1。当处于 gain 为 1.25 的 phase 时,意味着 pacing rate 是当前计算的合理值的 1.25 倍,此时 BBR 发送速率也会变成正常情况下的 1.25 倍(踩油门)。而当处于 gain 为 0.75 的 phase 时,相应的发送速率是正常情况的 0.75 倍(踩刹车)。而 gain 为 1 时,发送速率就是正常值(巡航).

BBR 一脚油门一脚刹车的组合保证了当链路带宽不变时,这条流不会向链路灌入超量的报文。而 6/8 时间段里的 gain 为 1 又使得大部分时候,采用 BBR 控制的 流发送报文的 pacing rate 是稳定的。

探测有三种结果

Probe RTT 状态

Probe RTT 状态的目的是为了探测链路的固有往返时延(RTprop),如果 min-RTT 在 10s 内没有刷新,则无论之前在哪个状态,BBR 都会强制将流的状态切换到 Probe RTT。

进入 Probe RTT 状态后,BBR 会将 cwnd 限制到一个非常小的值(4),并持续至少 200ms, 目的是保证这条流不会引起中间设备上的报文堆积。

BBR 的性能结果

BBR 在有一定丢包率的网络环境中性能大幅度领先于 CUBIC

与[转帖]理解 BBR 拥塞控制算法--理论篇相似的内容:

[转帖]理解 BBR 拥塞控制算法--理论篇

https://switch-router.gitee.io/blog/bbr1/ 简介 BBR (Bottleneck Bandwidth and Round-trip propagation time)是 Google 在 2016 年发布的一套拥塞控制算法。它尤其适合在存在一定丢包率的弱网环境

[转帖]理解开源安全中的林纳斯定律

https://linux.cn/article-15344-1.html 林纳斯定律Linus's Law即“只要有足够多的眼睛关注,任何漏洞都无处隐藏given enough eyeballs, all bugs are shallow”。那么林纳斯定律是如何应用于开源软件安全的呢? 这篇文章讨

[转帖]「理解C++20协程原理」从Linux线程、线程与异步编程、协程与异步

协程不是系统级线程,很多时候协程被称为“轻量级线程”、“微线程”、“纤程(fiber)”等。简单来说可以认为协程是线程里不同的函数,这些函数之间可以相互快速切换。 协程和用户态线程非常接近,用户态线程之间的切换不需要陷入内核,但部分操作系统中用户态线程的切换需要内核态线程的辅助。 协程是编程语言(或

[转帖]理解平均负载

https://www.jianshu.com/p/beb0b9f590d4 uptime命令 [test@localhost bin]$ uptime 22:02:14 up 3:34, 2 users, load average: 0.00, 0.01, 0.05 #22:02:14 //当前时

[转帖]理解 LSTM 网络

https://www.jianshu.com/p/9dc9f41f0b29 作者: Christopher Olah (OpenAI)译者:朱小虎 Xiaohu (Neil) Zhu(CSAGI / University AI)原文链接:https://colah.github.io/posts/

[转帖]理解 postgresql.conf 的work_mem 参数配置

https://developer.aliyun.com/article/401250 简介: 主要是通过具体的实验来理解 work_mem 今天我们着重来了解 postgresql.conf 中的 work_mem 参数 官方文档描述如下: 指定在写入临时文件之前内部排序操作和散列表使用的内存量。

[转帖]深入理解同步机制---内核自旋锁

https://switch-router.gitee.io/blog/spinlock/ 进程(线程)间的同步机制是面试时的常见问题,所以准备用一个系列来好好整理下用户态与内核态的各种同步机制。本文就以内核空间的一种基础同步机制—自旋锁开始好了 自旋锁是什么 自旋锁就是一个二状态的原子(atomi

[转帖]【翻译】理解 TCP/IP 网络栈

https://cizixs.com/2017/07/27/understand-tcp-ip-network-stack/ TL;DR [TOC] 译者注:很久没有翻译文章了,最近在网络看到这篇介绍网络栈的文章非常详细,正好最近在看这方面的内容,索性翻译过来。因为很多文章比较长,而且很多内容比较专

[转帖]深入理解SQL的四种连接-左外连接、右外连接、内连接、全连接

https://www.cnblogs.com/jiangjunli/p/10617034.html 1、内联接(典型的联接运算,使用像 = 或 <> 之类的比较运算符)。包括相等联接和自然联接。 内联接使用比较运算符根据每个表共有的列的值匹配两个表中的行。例如,检索 students和course

[转帖]深入理解Redis的持久化

https://www.cnblogs.com/ivictor/p/9749465.html RDB RDB是将当前数据生成快照保存到硬盘上。 RDB的工作流程: 1. 执行bgsave命令,Redis父进程判断当前是否存在正在执行的子进程,如RDB/AOF子进程,如果存在bgsave命令直接返回。