2.6 网络拥塞控制原理与实践
你可能听说过与 TCP/IP 协议相关的术语,如 Cubic、Tahoe、Vegas、Reno、Westwood 以及近年来流行的 BBR 算法,这些都是网络传输层使用的拥塞控制算法。
拥塞控制算法直接影响网络吞吐(throughput)的效率。本节,我们分析拥塞控制的原理,回顾不同阶段互联网拥塞控制算法的设计,并深入探讨 BBR 算法如何在弱网环境下显著提升网络吞吐效率。
2.6.1 网络拥塞控制原理
网络吞吐效率与 RTT 和传输速率密切相关:
- RTT 越低,数据传输的延迟越短;
- 传输速率越高,网络在单位时间内处理的数据越多。
图 2-22 展示了这两者的变化逻辑及其对网络传输效率的影响。
图 2-22 RTT 与传输速率变化对网络吞吐效率的影响
首先,解释图中的一些术语,它们的含义如下:
- RTprop (Round-Trip propagation time,两个节点之间最小时延):两个节点之间的最小时延,取决于物理距离,距离越长,时延越大。
- BtlBw(Bottleneck Bandwidth,瓶颈带宽):如果把网络链路想象成水管,RTprop 是水管的长度,BtlBw 则是水管最窄处的直径。
- BDP(Bandwidth-Delay Product,带宽和延迟的乘积):它代表了网络上能够同时容纳的数据量(水管中有多少流动的水)。 BDP 的计算公式是:BDP = 带宽 × 延迟。其中,带宽以比特每秒(bps)为单位,延迟以秒为单位。
- inflight 数据:指已经发送出去但尚未收到确认的数据包。这些数据包仍在网络中传输,等待接收方的处理或确认。。
受 RTT 和传输速率的影响,图 2-22 被分成了三个区间:
- (0,BDP):称为“应用受限区”(app limited)。这个区间内,inflight 数据量未占满瓶颈带宽。RTT 最小、传输速率最高。
- (BDP,BtlBwBuffSize):称为“带宽受限区”(bandwidth limited)。这个区间内,inflight 数据量已达到链路瓶颈容量,但尚未超过瓶颈容量加缓冲区容量。此时,应用能发送的数据量主要受带宽限制。RTT 逐渐变大,传输速率到达上限。
- (BDP + BtlBwBuffSize,infinity):称为“缓冲受限区”(buffer limited)。这个区间内,实际发送速率已超过瓶颈容量加缓冲区容量,超出部分的数据会被丢弃,从而产生丢包。RTT 以及传输速率均达到上限。
根据图 2-22,可以看出,拥塞的本质在于 inflight 数据量持续偏离 BDP 线向右扩展,而拥塞控制的关键在于调节 inflight 数据量保持在合适的区间内。显然,当 inflight 数据量位于应用受限区与带宽受限区的边界时,传输速率接近瓶颈带宽,且无丢包发生。
2.6.2 早期拥塞控制旨在收敛
早期互联网的拥塞控制以丢包为控制条件,控制逻辑如图 2-21 所示。
发送方维护一个称拥塞窗口的状态变量 cwnd,其值取决于网络拥塞的程度和所采用的拥塞控制算法。当发送方开始发送数据时,进入慢启动(Slow Start)阶段,也就是慢慢增大拥塞控制窗口;当出现丢包时,进行拥塞避免(Congestion Avoiance)阶段,也就是减小拥塞控制窗口;当丢包不再出现时,再次进入慢启动阶段,如此一直反复。
图 2-21 早期以丢包为条件的拥塞控制
以丢包为控制条件的机制适应了早期互联网的特征:低带宽和浅缓存队列。
随着移动互联网的快速发展,特别是图片和音视频应用的普及,网络负载大幅增加。与此同时,摩尔定律推动设备的性能不断提升和成本不断降低。当路由器、网关等设备的缓存队列增加,网络链路变得更长、更宽时,RTT 可能因缓存队列增大而增加,丢包则可能源于链路过长。网络变差,并不总是因链路拥塞所致。
因此,以丢包为控制条件的传统拥塞控制算法就不再适用了。
2.6.3 现代拥塞控制旨在效能最大化
如果说早期的拥塞控制算法目的在于收敛,防止互联网服务发生“拥塞崩溃”。那么,BBR 的目标则是充分利用链路带宽和路由/网关设备的缓存队列,最大化网络效能。
最大化网络效能的前提是找到网络传输中的最优点,图 2-22 中的两个黑色圆圈即代表网络传输的最优点:
- 上面的圆圈为 min RTT(延迟极小值):此时,网络中路由/网关设备的 Buffer 未占满,没有任何丢包情况;
- 下面圆圈的为 max BW(带宽极大值):此时,网络中路由/网关设备的 Buffer 被充分利用。
当网络传输处于最优点时:
- 数据包投递率 = BtlBW(瓶颈带宽),保证了瓶颈链路被 100% 利用;
- 在途数据包总数 = BDP(时延带宽积),保证了 Buffer 的利用合理。
然而,最小延迟与最大带宽互相矛盾,无法同时测量。如图 2-24 所示:测量最大带宽时,必须填满瓶颈链路,此时缓冲区被沾满,导致延迟增大;测量最小延迟时,需确保缓冲区为空,这又无法测得最大带宽。
图 2-24 无法同时得到 max BW 和 min RTT
2.6.4 BBR 的设计原理
BBR 的解题思路是不再考虑丢包作为拥塞的判断条件,而是交替测量带宽和延迟。
BBR 通过观测一段时间内的最大带宽和最小延迟来估算发包速率。稳定控制发送速度的同时,尽可能充分榨干带宽:
- 为了最大化带宽利用率,BBR 周期性探测链路条件的改善,并在检测到带宽提升时增加发包速率;
- 为了防止数据在中间设备缓存队列中堆积,BBR 定期探测链路的最小 RTT,并根据最小 RTT 调整发包速率。
BBR 的拥塞控制状态机是实现上述设计的核心基础。该状态机在任何时刻处于以下四种状态之一:启动(STARTUP)、排空(DRAIN)、带宽探测(PROBE_BW)和时延探测(PROBE_RTT)。这四种状态的含义以及转换关系如图 2-23 所示。
- 启动阶段(STARTUP):连接建立时,BBR 采用类似传统拥塞控制的慢启动方式,指数级提升发送速率,目的是尽快找到最大带宽。当在连续一段时间内检测到发送速率不再增加,说明瓶颈带宽已达到,此时状态切换至排空阶段。
- 排空阶段(DRAIN):此阶段通过指数级降低发送速率,执行启动阶段的反向操作,目的是逐步清空缓冲区中的多余数据包。
- 带宽探测阶段(PROBE_BW):完成启动和排空阶段后,BBR 进入带宽探测阶段,这是 BBR 主要运行的状态。当 BBR 探测到最大带宽和最小延迟,并且在途数据量(inflight)等于 BDP 时,BBR 以稳定的速率维持网络状态,并偶尔小幅提速探测更大的带宽或小幅降速以公平释放带宽。
- 时延探测阶段(PROBE_RTT):如果未检测到比前一周期更小的最小 RTT,则进入时延探测阶段。在该状态下,拥塞窗口(Cwnd)被设定为 4 个 MSS(最大报文段长度),并重新测量 RTT,持续 200ms。超时后,根据网络带宽是否已满载,决定切换至启动阶段或带宽探测阶段。
图 2-23 BBR 状态转移关系
2.6.5 BBR 的应用
Linux 内核从 4.9 开始集成了 BBR 拥塞控制算法。此后,在绝大数的 Linux 发行版中,只要几个命令就能使用 BBR 提升网络传输效率。
- 首先,查询系统所支持的拥塞控制算法。
$ sysctl net.ipv4.tcp_available_congestion_control
net.ipv4.tcp_congestion_control = bbr cubic reno
上面返回的结果中,显示当前系统支持 bbr、cubic 和 reno 三种拥塞控制算法。
- 查询当前使用的拥塞控制算法。
$ sysctl net.ipv4.tcp_congestion_control
net.ipv4.tcp_congestion_control = cubic
绝大部分 Linux 系统默认的拥塞控制算法为 Cubic 算法。
- 指定拥塞控制算法为 bbr。
$ echo net.ipv4.tcp_congestion_control=bbr >> /etc/sysctl.conf && sysctl -p
网络拥塞控制是单向生效,也就是说作为下行方的服务端调整了,BBR 算法即可生效。
2.6.6 BBR 性能表现
接下来,我们使用 tc 工具模拟弱网环境,使用网络性能测试工具 iperf3 测试弱网环境下不同的拥塞控制算法的表现。
首先,在服务端设置 eth0 网络接口上的流量丢包率为 1%、延迟为 25ms。
$ tc qdisc add dev eth0 root netem loss 1% latency 25ms
接着,在服务端使用 iperf3 开启测试服务,以服务端模式运行,设置监控时间2秒,并指定端口为 8080。
$ iperf -s -p 8080 -i 1
在客户端节点使用 iperf3 以客户端模式运行,请求 10.0.1.188 服务端的 8080 端口。
$ iperf3 -c 10.0.1.188 -p 8080
测试结果如表 2-3 所示。可以看出,BBR 在轻微丢包的网络环境下表现尤为出色。
表 2-3 不同网络环境下,各拥塞控制算法的网络吞吐表现 表数据来源
服务端的拥塞控制算法 | 延迟 | 丢包率 | 网络吞吐表现 |
---|---|---|---|
Cubic | <1ms | 0% | 2.35Gb/s |
Reno | <140ms | 0% | 195 Mb/s |
Cubic | <140ms | 0% | 147 Mb/s |
Westwood | <140ms | 0% | 344 Mb/s |
BBR | <140ms | 0% | 340 Mb/s |
Reno | <140ms | 1.5% | 1.13 Mb/s |
Cubic | <140ms | 1.5% | 1.23 Mb/s |
Westwood | <140ms | 1.5% | 2.46 Mb/s |
BBR | <140ms | 1.5% | 160 Mb/s |
Reno | <140ms | 3% | 0.65 Mb/s |
Cubic | <140ms | 3% | 0.78 Mb/s |
Westwood | <140ms | 3% | 0.97 Mb/s |
BBR | <140ms | 3% | 132 Mb/s |