发送窗口、接收窗口和拥塞窗口
滑动窗口机制中涉及三个重要概念:
- 发送窗口
发送窗口是发送端在操作系统内开辟的一块缓冲区,用来存放当前需要发送的数据,也称为发送缓存。发送端使用发送窗口进行流量控制。
- 接收窗口(RWND,Receiver Window)
接收窗口是接收端在操作系统内开辟的一块缓冲区,设备会将收到的来不及处理的报文放入接收缓冲区,也称为接收缓存。接收端使用接收窗口进行流量控制。
- 拥塞窗口(CWND,Congestion Window)
拥塞窗口是发送端根据自己估计的网络拥塞程度而设置的窗口值。发送端使用拥塞窗口进行流量控制。
通常TCP通信是双向的,所以,每台设备会同时存在发送窗口和接收窗口。
滑动窗口的大小是如何确定的呢?
- 接收窗口的大小等于接收端目前接收缓冲区的大小,表示接收端当前可以接收报文的能力。接收端将此窗口值放在TCP报文首部中的窗口(WIN)字段,传送给发送端。
- 拥塞窗口的确定原则为:如果网络没有出现拥塞,发送端就使拥塞窗口增大一些,以便将更多的数据发送出去;如果网络出现拥塞,发送端就使拥塞窗口减小一些,以便减小数据的发送。如何判断网络是否出现拥塞,拥塞窗口增加和减小的幅度,均由拥塞控制算法决定,下文将详细描述。
- 大部分情况下,发送端和接收端之间通过交换机、路由器等网络传输设备相连,这些传输设备的接收、处理能力各不相同,各设备之间链路的速率也不一样,所以,发送窗口大小由接收端的接收能力(即接收端接收窗口的大小)以及网络的传输能力(即拥塞窗口大小)共同决定。
发送窗口的大小=Min[接收窗口RWND, 拥塞窗口CWND],即发送窗口的大小取接收窗口和拥塞窗口中值较小的那个。
¡ 当接收窗口小于拥塞窗口时,接收端的接收能力限制发送窗口的大小;
¡ 当拥塞窗口小于接收窗口时,网络的拥塞限制发送窗口的大小。
对于广域网设备之间建立的TCP连接,因为发送端和接收端均为广域网设备,广域网设备的接收缓冲区足够大(从几十到几万KB,用户可以通过命令行配置),会远大于拥塞窗口的大小。所以,广域网设备的发送窗口只受拥塞窗口的约束,发送窗口的大小直接取拥塞窗口CWND的大小。
BBR技术实现
1.1 概念介绍
1. BtlBw(瓶颈带宽)
瓶颈带宽指一条传输链路的最大传输能力。BBR(Bottleneck Bandwidth and RTT,瓶颈带宽和往返时延)使用瓶颈带宽BtlBw来控制发送端可发送的报文数量以及发包速率。发送端使用报文送达率(即一段时间内送达的报文数/对应的时间间隔)来计算即时带宽,再根据即时带宽和Kathleen Nichols算法,来估计瓶颈带宽BtlBw。
2. RTprop(往返时延RTT极小值)
RTprop指链路中没有排队且无丢包时,一个包在链路中一个来回所需的时长,即往返时延RTT的极小值。
3. 增益系数
BBR定义了两个增益系数:
- 发送速率增益系数pacing_gain:表示发送速率的调整倍数。
- 发送窗口增益系数cwnd_gain:表示发送窗口的调整倍数。
BBR算法定义了StartUp(启动阶段)、Drain(排空阶段)、ProbeBW(BtlBw探测阶段)、ProbeRTT(RTprop探测阶段)四个状态机,并为不同状态机指定了不同的增益系数,通过调整各状态机下的增益系数来调整网络中的报文数量,以便感知带宽、RTT的变化。
- StartUp阶段:pacing_gain取值为2.89,cwnd_gain取值为2.89。
- Drain阶段:pacing_gain取值为0.35,cwnd_gain取值为2.89。
- ProbeBW阶段:ProbeBW阶段又分为8个小区段,在这8个小区段内,pacing_gain取值分别为5/4、3/4、1、1、1、1、1、1,cwnd_gain取值为2。
- ProbeRTT阶段:pacing_gain取值为1,cwnd_gain取值为1。
1.2 BBR算法原理
BBR算法基于测量反馈来主动调整拥塞窗口CWND和报文发送速率,从而提高带宽利用率,避免网络拥塞。BBR主要使用报文发送速率控制发送端发送报文的速度,以免报文发送过快,导致接收设备来不及处理报文,导致报文积压;BBR辅助使用拥塞窗口CWND控制发送端发送的报文总量,以免发送端发送的报文总数过多造成网络拥塞。
BBR算法的基本原理为:
- 发送端根据发送的报文段以及收到的ACK反馈持续测量往返时延RTT,并计算网络即时带宽BW。将当前获得的即时带宽BW、往返时延RTT和历史瓶颈带宽BtlBw(初始值为0)、历史往返时延RTT极小值RTprop(初始值较大,为64位十六进制数全f)比较,并根据Kathleen Nichols算法,得到当前瓶颈带宽BtlBw和当前往返时延RTT极小值RTprop。
- BBR使用得到的瓶颈带宽BtlBw和RTT极小值RTprop,乘以发送速率增益系数pacing_gain、发送窗口增益系数cwnd_gain,计算出下次发送的拥塞窗口CWND和发包速率。
¡ 实际发包速率pacing_rate=pacing_gain * BtlBw
¡ 拥塞窗口CWND=max(cwnd_gain * BtlBw * RTprop, 4)
- BBR找到瓶颈带宽BtlBw和RTT极小值RTprop后,大部分时间会以瓶颈带宽BtlBw作为实际发包速率平稳发包。然后小幅增大或减少实际发包速率,来探测新的BtlBw和RTprop,以便适应网络环境的变化。
1.3 BBR的实现过程
BBR通过以下四个状态,来交替循环探测,得出BtlBw和RTprop:StartUp(启动阶段)、Drain(排空阶段)、ProbeBW(BtlBw探测阶段)、ProbeRTT(RTprop探测阶段)。
为了获得瓶颈带宽BtlBw,BBR会增加发包数量,可能会造成报文被缓存在链路的队列中,导致往返时延RTT增加;而为了测量RTT极小值RTprop,需要清空当前链路队列中的缓存。因此,不能同时探测得出瓶颈带宽BtlBw和RTprop,需要交替循环探测得出瓶颈带宽BtlBw和RTprop。
1.3.1 StartUP(启动阶段)
TCP连接建立后,BBR算法启动并进入StartUP状态。StartUP状态对应BBR算法的启动阶段,目标是获得当前瓶颈带宽BtlBw。
为了快速探测到最佳发包速率,StartUP状态下,BBR规定发包增益系数为pacing_gain=2.89,当前发包速率=pacing_gain*BtlBw=2.89*BtlBw。
BBR探测瓶颈带宽BtlBw的流程如下:
(1) 初始情况下,发送端以一个较低发包速率向接收端发送报文,获得当前的即时带宽BW。BW>当前的瓶颈带宽BtlBw(初始值为0),更新瓶颈带宽BtlBw=即时带宽BW。
(2) 更新发包速率,当前发包速率=pacing_gain*BtlBw=2.89*BtlBw。发送端以更高的发布速率发包。
(3) BBR继续更新瓶颈带宽BtlBw,使用新的瓶颈带宽BtlBw计算新的发包速率,用新的发包速率发送报文。
如果BBR连续3次探测、计算得到的即时带宽BW均小于当前瓶颈带宽BtlBw的1.25倍,则说明已经获得了当前瓶颈带宽BtlBw,且链路可能出现了发包缓存现象,BBR进入Drain状态。
1.3.2 Drain状态(排空阶段)
因为在StartUP状态BBR以2.89倍速增加发包速率,随着发包速率的不断增长,链路中可能出现发包缓存现象(网络传输设备、接收端将来不及处理的报文存放到接收缓冲区)。发包缓存意味着报文到达接收设备时不能立即被处理,这会导致往返时延RTT增大,当越来越多的报文被缓存,可能会导致接收设备的接收缓冲区被占满,报文被丢弃。TCP需要重传报文,导致传输性能急剧恶化。
BBR追求带宽利用率最高,即以瓶颈带宽BtlBw发包,同时,链路中尽量不要出现发包缓存,以便报文能以最快速度、最短时间送达接收端。于是在StartUP状态后,BBR会进入Drain状态,用于排空StartUP状态下,链路中缓存的报文。
BBR排空链路中缓存报文的流程如下:
(1) 为了排空链路中缓存的报文,BBR需要降低发包速度。Drain状态下,协议规定发包增益系数pacing_gain=0.35,发包速率=pacing_gain*BtlBw=0.35*BtlBw。
(2) BBR以0.35*BtlBw速率发包,直至BBR检测到链路中正在传输的报文数小于BtlBw*RTprop。此时BBR认为链路队列中缓存的报文已经排空,进入ProbeBW状态。
1.3.3 ProbeBW状态(BtlBw探测阶段)
探测到瓶颈带宽BtlBw,并排空链路中缓存的报文后,BBR进入ProbeBW状态。在该阶段,BBR大部分时间以瓶颈带宽BtlBw作为发包速率平稳发包,小部分时间会小幅调整发包速率,来探测新的瓶颈带宽BtlBw。
BBR绝大部分时间处于ProbeBW状态。该状态以8个RTT为周期循环滚动,包括6个平稳周期、1个上升周期、1个减少周期:
- 6个平稳周期:为了充分利用网络带宽,BBR在6个RTT内进行平稳发包。此时的发包增益系数pacing_gain=1,发包速率=pacing_gain*BtlBw=1*BtlBw。
- 1个上升周期:为了探测更高的BtlBw,BBR在1个RTT内短暂地提高发包速率。此时的发包增益系数pacing_gain=1.25,发包速率=pacing_gain*BtlBw=1.25*BtlBw。
- 1个减少周期:为了排空链路队列中可能缓存的报文,BBR在1个RTT内短暂地降低发包速率。此时的发包增益系数pacing_gain=0.75,发包速率=pacing_gain*BtlBw=0.75*BtlBw。
1.3.4 ProbeRTT状态(RTprop探测阶段)
RTprop指链路中没有排队且无丢包时,一个包在链路中一个来回所需的时长,即往返时延RTT的极小值。通常情况下,链路创建后,RTprop即为固定值。但传输网络是共享网络,链路中没有本连接发送的报文,但是可能有其它会话发送的报文,所以,为了确保RTprop值的可靠性,BBR会检测RTprop值的刷新状态。若超过10秒RTprop还未更新,则无论当前BBR处在StartUP、Drain和ProbeBW中的哪个状态,均进入RTprop状态。
进入RTprop状态后,BBR将CWND拥塞窗口CWND减小到4并持续200毫秒,通过断崖式减少发包来清空链路中缓存的报文,以便探测新的RTprop。
1.4 BBR算法总结
相比Reno和BIC,BBR的优势主要体现在以下方面:
- BBR基于周期探测结果来调整拥塞窗口CWND,不以丢包为触发拥塞控制的条件,比Reno和BIC更合理,更高效。
- Reno和BIC使用拥塞窗口CWND控制发包,它的尽力发送势必导致链路中报文被队列缓存,报文在网络中的传输时延增加。队列缓存越大,时延越严重。BBR使用发包速率和拥塞窗口CWND双重参数控制发包,能将突发报文平滑发送。而且BBR会定期降速发包,清空链路中队列里缓存的报文,能够有效地降低网络时延。
- BBR绝大部分时间平稳发包,而Reno和BIC需要循环探测、丢包、快速恢复、探测,BBR带宽利用率更高,吞吐量更大。
当然,BBR也有使用约束:由于BBR的周期性特点,以及ProbeBW状态增加周期的增速限额(1.25* BtlBw)和减少周期的减速限额(0.75* BtlBw),导致当网络带宽增加或者减少时,BBR的抢占能力不如BIC。BIC反应迅速,如果链路中大部分为持续时间短的TCP连接,则使用BIC的传输效率更高。
如图7所示,BBR经过StartUp和Drain阶段后,进入相对平稳的发包阶段,相同时间段内BBR的吞吐量要大于Reno和BIC。当网络传输能力提高,最佳拥塞窗口CWND从30个MSS提升到48个MSS,BIC最少只需5个RTT即可达到最佳拥塞窗口CWND,而BBR需要7个RTT,拥塞窗口CWND才上升到1.25*30=37.5(取37个MSS),BBR再经过8个RTT,拥塞窗口CWND上升到1.25*37=46.25(取46个MSS)。
下图Reno、BIC和BBR算法原理示意图
1.5 BBRv2简介
标准BBR的实现称为BBRv1,为了弥补BBRv1在多种算法(BBR、BIC算法)共存的网络中带宽抢占能力方面的使用约束,BBR又衍生出了BBRv2。BBRv2是对BBRv1的优化,优化的方面包括但不仅限于:
- BBRv2在Startup状态,增加了丢包退出判断条件。为避免更严重地丢包,在Startup状态,只要检测到丢包,则退出Startup状态,而不用等到“连续3次探测计算得到的即时带宽BW均小于当前瓶颈带宽BtlBw的1.25倍”。
- 为了快速响应网络变化,TCP需要及时调节拥塞窗口CWND,通过加快ProbeRTT的更新可实现拥塞窗口CWND值的快速调节。BBRv2将进入RTprop状态的触发条件从10秒减小到2.5秒。即若持续2.5秒RTprop一直未更新,则BBRv2立即进入ProbeRTT状态,来探测新的RTprop。
- 为了减小进入ProbeRTT状态带来的带宽波动,进入ProbeRTT状态后,BBRv2将拥塞窗口CWND减少到0.5*BtlBw*RTprop,而BBRv1将拥塞窗口CWND减少到4。
2 拥塞控制算法比较
Reno、BIC通过拥塞窗口CWND来控制发送端可发送的报文的数量,BBR通过网络最大带宽BtlBw和RTprop(极小RTT)控制发送端发送报文的速度和数量。它们最大的差别在于链路最大带宽的探测机制不同。总体趋势来说:
- 收敛速度(从快到慢):BBR>BIC>Reno
- 公平性(深缓存场景下的抢占能力,从强到弱):BIC>BBR>Reno
- 抗丢包能力(从强到弱):BBR>BIC>Reno
- 网络排队时延(从低到高):BBR<Reno<BIC
深缓存指链路中具有比较大的缓存,例如接收缓存、中间设备的缓存队列等。
算法 |
关键技术 |
推荐使用场景 |
Reno |
· 将丢包作为拥塞控制的触发条件,不区分丢包原因是错包还是真正的网络拥塞,容易误判 · 检测到丢包时,拥塞窗口CWND减半 · 线性增长探测拥塞窗口CWND,每经过一个RTT,拥塞窗口CWND加1 |
低丢包率、低带宽、对时延要求低的场景 |
BIC |
· 将丢包作为拥塞控制的触发条件,不区分丢包原因是错包还是真正的网络拥塞,容易误判 · 检测到丢包时,拥塞窗口CWND减半 · 用二分搜索法和乘性增加法探测拥塞窗口CWND |
低丢包率、高带宽、对时延要求低的场景 |
BBRv1 |
不将丢包作为拥塞控制的触发条件,以周期探测的时延和带宽为依据,计算拥塞窗口CWND和发送速率,平稳发包 |
存在一定丢包率、高带宽、对时延要求高、BBR算法单独使用的场景 |
BBRv2 |
相比于BBRv1: · BBRv2在Startup状态,只要检测到丢包,则退出Startup状态,来避免更严重地丢包 · BBRv2将进入RTprop状态的触发条件从10秒减小到2.5秒(若持续2.5秒RTprop一直未更新,则BBRv2立即进入ProbeRTT状态,来探测新的RTprop),来及时调节拥塞窗口CWND,以便快速响应网络变化 · BBRv2进入ProbeRTT状态后,BBRv2将拥塞窗口CWND减少到0.5*BtlBw*RTprop(BBRv1将拥塞窗口CWND减少到4),来减小进入ProbeRTT状态带来的带宽波动 |
存在一定丢包率、高带宽、对时延要求高、各种算法共存的场景 |