
文章插图
发送速率和RTT vs inflight
RTProp : round-trip propagation time BtlBW : bottleneck bandwidth
基于丢包的拥塞控制算法工作在 bandwidth-limited 区域的右边界区域,尽管这种算法可以达到最大的传输速率,但是它是以高延迟和高丢包率作为代价的 。在存储介质较为小的时候,缓存大小只比 BDP 大一点,此时这种算法的时延并不会很高 。然而,当存储介质变得便宜之后,交换机的缓存大小已经是 ISP 链路 BDP 的很多很多倍了,这导致了 bufferbloat,从而导致了 RTT 从毫秒级升到了秒级 。
当一个连接满足以下两个条件时,它可以在达到最高的吞吐量的同时保持最低时延:
1)速率平衡:瓶颈带宽的数据到达速率与 BtlBw 相等;
2)填满管道:所有的在外数据(inflight data)与 BDP(带宽与时延的乘积)相等
bbr 算法关于拥塞窗口的核心就是计算 BtlBW 和 RTprop,根据这两者值计算 BDP 。BtlBw 和 RTprop 可能是动态变化的,所以需要实时地对它们进行估计 。
计算 RTprop
目前 TCP 为了检测丢包,必须实时地跟踪 RTT 的大小 。在任意的时间 t,

文章插图
表示“噪音” 。造成噪声的因素主要有:链路队列,接收方的时延 ACK 配置,ACK 聚合等因素等待 。RTprop 是路径的物理特性,并且只有路径变化才会改变 。由于一般来说路径变化的时间尺度远远大于 RTprop,所以 RTprop 可以由以下公式进行估计:

文章插图
即,在一个时间窗口中对 RTT 取最小值 。一般将该窗口大小设置为几十秒至几分钟 。
计算 BtlBW
bottleneck bandwidth 的估计不像 RTT 那样方便,没有一种 TCPspec 要求实现算法来跟踪估计 bottleneck 带宽,但是,可以通过跟踪发送速率来估计 bottleneck 带宽 。当发送方收到一个 ACK 报文时,它可以计算出该报文的 RTT,并且从发出报文到收到 ack 报文这段时间的 data Inflight 。这段时间内的平均发送速率就可以以此计算出来:

文章插图
这个计算出的速率必定小于 bottleneck 速率(因为 delta delivered 是确定的,但是 deltat 会较大) 。因此,BtlBw 可以根据以下公式进行估计 。

文章插图
其中,时间窗口大小的值一般为 6~10 个 RTT 。
TCP 必须记录每个报文的离开时间从而计算 RTT 。BBR 必须额外记录已经发送的数据大小,使得在收到每一个 ACK 之后,计算 RTT 及发送速率的值,最后得到 RTprop 和 BtlBw 的估计值 。
6.3.2 pacing_rate 和 cwndbbr 算法输出 pacing_rate 和 cwnd 两个数据 。pacing_rate 决定发包速率,cwnd 为窗口大小 。每一次 ACK 都会根据当前的模式计算 pacing_rate 和 cwnd 。注意在计算 pacing_rate 和 cwnd 时有 pacing_gain 和 cwnd_gain 两个参数,
bottleneck_bandwidth = windowed_max(delivered / elapsed, 10 round trips)min_rtt = windowed_min(rtt, 10 seconds)pacing_rate = pacing_gain * bottleneck_bandwidthcwnd = max(cwnd_gain * bottleneck_bandwidth * min_rtt, 4)
文章插图
BBR 和 Pacing rate
6.3.3 BBR 状态机BBR 算法也是基于状态机 。状态机有STARTUP、DRAIN、PROBE_BW、PROBE_RTT四种状态 。不同状态下pacing_gain 和 cwnd_gain 的取值会有所不同 。

文章插图
bbr 状态机
STARTUP:初始状态,该状态下类似于传统拥塞控制的慢启动阶段 。该状态下pacing_gain和cwnd_gain为2/ln(2)+1 。因为这是最小的能够达到 Reno 或者 CUBIC 算法启动速度的值 。
/* We use a high_gain value of 2/ln(2) because it's the smallest pacing gain * that will allow a smoothly increasing pacing rate that will double each RTT * and send the same number of packets per RTT that an un-paced, slow-starting * Reno or CUBIC flow would: */static const int bbr_high_gain= BBR_UNIT * 2885 / 1000 + 1;DRAIN:该状态为排除状态 。在STARTUP状态下三轮没有涨幅超过 25%时会进入该状态 。该状态下BtlBw会根据bbr_drain_gain逐渐降低,直到 inflight 降到 BDP 为止 。/* The pacing gain of 1/high_gain in BBR_DRAIN is calculated to typically drain * the queue created in BBR_STARTUP in a single round: */static const int bbr_drain_gain = BBR_UNIT * 1000 / 2885;
推荐阅读
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 如何基于TCP/IP协议进行MFC Socket网络通讯编程
- Treck TCP/IP协议库多个漏洞安全风险通告
- tcp,icmp,http 基于wireshark报文分析快速过滤报文时延
- 服务器海量TCP连接如何高效保活?
- 两万字深度介绍分布式,一文入魂
- TCP 半连接队列和全连接队列满了,怎么破?
- 说起来 TCP 的连接与释放真是个浪漫的故事呢!
- 网络安全常见协议解析:TCP、UDP、HTTP、FTP、SMTP等之间的区别
- 全网最强TCP/IP拥塞控制总结
- 轻松学习http知识让枯燥的内容变得生动有趣:TCP/IP四层模型
