BBR 算法原理三

奋斗吧
奋斗吧
擅长邻域:未填写

标签: BBR 算法原理三 Python博客 51CTO博客

2023-04-17 18:23:53 259浏览

BBR 算法原理三,稳态行为(Steady-statebehavior)BBR大部分时间都是在此状态路径适配与控制循环BBR的发送速率和发送数据量只是估计出的 BtlBw 和 RTprop 的一个函数,过滤器(filters)除了要对瓶颈进行估计之外,还要控制对传输路径的适配 (controladapta

稳态行为(Steady-state behavior)

BBR 大部分时间都是在此状态

路径适配与控制循环

BBR 的发送速率和发送数据量只是估计出的 BtlBw 和 RTprop

BBR 算法原理三_链路

Fig 2. RTT (blue), inflight (green), BtlBw max filter (black) and delivery rate (red) detail

从上到下四条横线:

  1. RTT
  2. inflight
  3. BtlBw 的估计值(状态)
  • 它上面的那行表格是pacing_gain,它是一个固定数组,不断循环;
  • 每个时刻使用的 pacing_gain 及其效果在图中是对齐的;
  • 每个 gain 会在发送数据时使用,因此是早一个 RTT 窗口;这可以从图中从下往上、再从上往下的整个环路看出来。
  1. delivery rate(实际传输速率)

几点说明:

  1. 图中凸起的尖峰是 BBR 使用 pacing_gain 周期切换导致的,目的是判断 BtlBw 是否有增加。
  2. BBR 在大部分时间都将 inflight 数据量保持在一个 BDP,并用 BtlBw estimate 进行 pace,以此来最小化延迟。 这将瓶颈从链路前移到了发送端,因此发送端是无法看到 BtlBw 升高的。

稳态的收敛过程

BBR 会定期使用 pacing_gain > 1

考虑链路瓶颈带宽 BtlBw 的两种可能情况:

  1. 继续保持恒定(大部分情况)
  2. 突然增大(例如物理链路扩容)

如果 BtlBw 恒定,

  • 增加的数据量会在瓶颈处创建一个 queue,这会导致 RTT 变大,但 

deliveryRate

  • 下一个 RTprop 窗口会以 

pacing_gain < 1

如果 BtlBw 增大了,

deliveryRate

  • 因此,BBR 会以指数级快速收敛到新的瓶颈速率。

图 3 展示了一个原本运行在 10-Mbps/40-ms

BBR 算法原理三_状态机_02

Fig 3. Bandwidth change

BBR 是一个 max-plus 控制系统(一种基于 max() 和加法操作的代数)的一个具体使用场景,这是一种基于非标准代数进行控制的新方式12。 这种方式允许 adaptation rate (由 max gain 控制)独立于 queue growth (由 average gain 控制)。 应用到这里,得到的就是一个简单、隐含的控制循环,其中,对物理限制的变化的适应过程, 由代表这些限制的 filters 自动处理。而传统控制系统则需要通过一个复杂状态机连接 起来的多个循环,才能完成同样效果。

 

BBR算法计算结果

  bbr算法不仅会输出类似于Cubic 等算法结果的cwnd,其实他最主要的计算结果是pacing rate。

毕竟cwnd仅仅规定了当前的TCP最多可以发送多少数据,Cubic等算法中并没有规定怎么把这么多数据发出去,在Linux的实现中,如果发出去这么多数据呢?简单而粗暴,突发!忽略接收端通告窗口的前提下,Linux会把cwnd一窗数据全部突发出去,而这往往会造成路由器的排队,在深队列的情况下,会测量出rtt剧烈地抖动。

bbr在计算cwnd的同时,还计算了一个与之适配的pacing rate,该pacing rate规定cwnd指示的一窗数据的数据包之间,以多大的时间间隔发送出去。

 

计算过程:

bbr只关心应答了多少数据,以及花了多长时间,两者相除就可以计算出bw。 bw = delivered/interval_us

也就是说bbr根本不管某一个应答是重传后的ACK确认的,正常ACK确认的,还是说SACK确认的。当然sack等其他逻辑会关注

 

pacing rate怎么计算

  用时间窗口内(默认10轮采样)最大BW。上一次采样的即时BW,用它来在可能的情况下更新时间窗口内的BW采样值集合。这次能否按照这个时间窗口内最大BW发送数据呢?

这样看当前的增益系数的值,设为G,那么BW*G就是pacing rate的值。

   至于说cwnd的计算可能要稍微复杂一点,cwnd其实描述了一条网络管道传输能力性能(rwnd描述了接收端缓冲区),因此cwnd其实就是这个管道的容量,也就是BDP。

bbr一直在持续搜集最小的RTT值,而G是增益系数,一开始设定好,所以pacing rate就出来了。

 

pacing_rate 和 cwnd

  bbr 算法输出 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_bandwidth
cwnd = max(cwnd_gain * bottleneck_bandwidth * min_rtt, 4)

 

BBR 状态机

  BBR 算法也是基于状态机。状态机有STARTUPDRAINPROBE_BWPROBE_RTT四种状态。不同状态下 pacing_gain 和 cwnd_gain 的取值会有所不同。

 

BBR 算法原理三_链路_03

 

STARTUP:初始状态,该状态下类似于传统拥塞控制的慢启动阶段。该状态下pacing_gaincwnd_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;
/* 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;
/* The gain for deriving steady-state cwnd tolerates delayed/stretched ACKs: */
static const int bbr_cwnd_gain  = BBR_UNIT * 2;

 

The startup stage of "pacing rate" relationship with time fixed point has the following:
The rate of change of the "pacing rate" is exactly equal to the current "pacing rate"

so,
let x be the time,Assuming that the RTT is constant, use it to normalize:
the BDP evolves as a function of time as f1(x)=2^x
the pacing rate evolves as a function of time as f2(x)=2^x

Let g(x) be the derivative of f1(x):
g(x)=f1'(x)=ln2*2^x

the derivative of f1'(x) is the rate, so g(x) is pacing rate.

let G be the pacing gain:
g(x+1) = G*g(x) = G*ln2*2^x = f2(x+1) = 2*2^x

so G*ln2*2^x = 2*2^x ==> G = 2/ln2

 

http代理服务器(3-4-7层代理)-网络事件库公共组件、内核kernel驱动 摄像头驱动 tcpip网络协议栈、netfilter、bridge 好像看过!!!! 但行好事 莫问前程 --身高体重180的胖子



好博客就要一起分享哦!分享海报

此处可发布评论

评论(0展开评论

暂无评论,快来写一下吧

展开评论

您可能感兴趣的博客

客服QQ 1913284695