BBR 对 buffer 的侵占

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6

BBR 声称 anti-bufferbloat 且内置状态机有主动 drain所以题目中使用了 “侵占”也可以用 “吞占”。

BBR ProbeBW ProbeUP 阶段以 1.25x 的增益加速退出条件inflight >= 1.25 * maxbw * minrtt。

BBR ProbeBW Drain 阶段以 0.75x 的增益降速。

单流场景下当 bw full即使 buffer 排队 maxbw 亦不再增加接下来的 Drain 阶段可将 queue 完全退回。但与多条异步 Loss-based 流共存场景当 bw full即使 buffer 排队ProbeUP 总能挤出一点带宽(带宽占比越大加速比越小)maxbw 增量 < 25%而异步流 base queue delay 几乎不变BBR 测得 BDP 会随 ProbeUP 一点点增加幸好有个 ProbeRTT 可以主动回退 queuing但要在 10s 之后。

用固定 10s 控制 buffer 侵占强度以及公平性不太合理但也只能靠这个。要么就调参10s -> 5s无论怎样BBR 的侵占行为是固有的。

在现实中我们并没有观测到上述怪象多亏 BBR 还有个 cwnd 作为 secondary controller。如果 cwnd 真如其论文所述是一个 secondary controller只需要在 inflight >= cwnd_gain * BDP 时切回 Reno 执行 AIMD 即可但有趣的是 与 Loss-based 流共存时最终 inflight 总是 >= cwnd_gain * BDP这算是劣币驱良币还是被大融合同化最终的世界还是属于 AIMD。

BBRv2 差不多就是这意思融入 AIMD 对 Loss 的反应但还保留着一张脸。BBRv2 本文不谈先从 cwnd the secondary controller 开始。

BBR 作为 rate-based cc如果每一次测量都准确BBR 按照 delivery rate 测量值对 pacing rate 进行调整即可在 BBR 状态机约束下按计算的 pacing rate 一直发下去完全不必引入 cwnd 作为 secondary controller。

但现实中每次测量滞后至少一个 RTT时间不可倒流未来不可预测BBR 不得不为未来保留 buffer这是固有的。本文描述 BBR 和 Loss-based 流共存时 cwnd 的意义。

因为 Loss-based 流导致 RTT baseline 可任意改变若不限制 BBR cwndBBR 会被带偏。BBR 只根据测量值被动收敛不会主动降速而 ProbeUP 总能挤出带宽BBR 便陷入和 Loss-based 流的军备竞赛最终在 Loss-based 流一次次收缩后挤占整个 buffer这和 BBR 的设计背道而驰。

BBR 引入 cwnd 作为 secondary controller 的动机可能是承认设计上不完备(这是缺陷BBR 流之间的收敛全靠抢加速比)后的兜底。问题是cwnd 多大合适足够大又不至于太大足够小又不至于太小。
cwnd 在传统 cc 意义上等同于 BDP而 BDP 用 inflight 考量考虑下图展示的场景
在这里插入图片描述

Loss-based 流的固有排队场景设 p = b / BBBR 各测量量如下

maxbw = (1 - p) * C (发生在 ProbeUP 阶段)

minrtt = p * B / C + R

BDP = (1 - p) * C * (p * B / C + R)

另一方面ProbeUP 倾向于超速发送探测来挤占带宽此时的 max-inflight 是 B * (1 - p) + R * maxbw。

BDP = f§ = (1 - p) * C * (p * B / C + R)

max-inflight = g§ = B * (1 - p) + R * (1 - p) *C

BCR 为常数p 不等于 1 时 化简上式

f§ 正比于 F§ = C * (p * B / C + R) = p * B + R * C

g§ 正比于 G§ = B + R * C

由于 p 只能在区间 (0, 1) 无限接近 1因此 F§ < G§。

这意味着 ProbeUP 时的 inflight 被 BDP 限制BBR 为 BDP 乘以一个 cwnd_gain 以摆脱 cwnd-limited该值一定要大于 ProbeUP 的 pacing_gain 来承载对未来的过估预测(简单波动原理ProbeUP gain 的效果一定要在一个 RTT 后才能被 sender 感知在此之前 sender 根据 maxbw * minrtt 计算的 BDP 体现不出 gain 效果因此 BDP 需要至少不小于 pacing_gain 的同步增益系数)但又不能太大以避免对 Loss-based 流的过度侵占。

cwnd_gain = g

cwnd = g * BDP 正比于 F’§ = g * F§

比较 F’§ 与 G§当 F’§ < G§属 cwnd-limitedF’§ >= G§BBR 可执行正常逻辑不受 cwnd 限制。

BBR 限定 cwnd_gain = 2解释是

Raising ProbeBW’s cwnd_gain to two allowed BBR to continue sending smoothly at the estimated delivery rate, even when ACKs are delayed by up to one RTT. This largely avoids stalls.

但这只是问题的一面问题的另一面在当前 BBR 流以外就是上文提到的那些。

我比较讨厌 BBR 论证的 “精确性”但凡测量值都是滞后的当你测量到某值时产生该值的瞬间已过去用这个值预测未来必须留 buffer。这是测不准的根本
在这里插入图片描述

本质上讲在 co-existence 场景 RTT 测不准delivery rate 也测不准。所以围绕精确测量的精确推导都是瞎扯。明明是统计量偏要算个精确值。

为什么 cwnd_gain 是 2而不是 2.8而不是 3也不是 1.8这个 2 只是一个 buffer 量是一个要参数。问这个问题就像问交换机 buffer 要配多大一样要用统计方法而不是单流行为计算。

BBR 的精确计算就像热力学发展之前人们对测量温度的态度一样企图通过测量每一个分子来计算温度。
回到上面关于 g 值的问题。设 cwnd = g * BDP = max-inflight所以

g * p = p

所以当 p < 1 / gcwnd-limitedp >= 1 / gBBR 可正常 ProbeUP。因此 BBR 在 ProbeBW 状态 ProbeUP 阶段最多占据 1 / g 的 buffer这有效保护了其它 Loss-based 流。

可见g 越大BBR 越倾向于占更多 bufferProbeUP 是 MI 过程间隔 8 rounds 的 ProbeUP 比长 RTT Loss-based 流的 AIMD 周期短很多由于 ProbeUP 几乎一定会挤占出带宽Drain 不会起太大作用BBR 在这种情况下更有侵占性。

相反的一面g 越小BBR 越低效g 无限接近于 1 时p 接近于 1BBR 总是 cwnd-limited失去 ProbeUP 的空间。
cwnd_gain = 2 意思是BBR 流最多仅能使用 1 - 1 / g = 1 / 2 的 buffer。

如文初所述BBR 没有主动降速机制不响应外部信号(即使丢包也会记住此前的 maxbw)这意味着它无法识别 Loss-based 流数量无论与 1 条还是 n 条 Loss-based 流共存对于 BBR 单流而言它都有能力侵占(注意这个用词) 1 / g 的 bufferBBR 流之间的共存靠加速比收敛但对和 Loss-based 流共存时的收敛无能为力。

因此 g 的值与 BBR 流的数量与 Loss-based 流的数量以及每条流的 RTT 均有关系这是个根据场景可调的参数不可能被 “Delayed and Stretched ACKs” 完全覆盖。类似的还有pacing_gain = 1.252885 / 1000… 为什么是 10s 而不是 8s

The RTprop filter window (10 seconds) is short enough to allow quick convergence if traffic levels or routes change, but long enough so that interactive applications (e.g., Web pages, remote procedure calls, video chunks) often have natural silences or low-rate periods within the window where the flow’s rate is low enough or long enough to drain its queue in the bottleneck.

这些都是经验值而不是算出来的。不过以上引用的解释是不是意味着我不能将 RTprop filter window 从 10s 改到 5s 了管他呢BBR 已经漏了。

我说过用 E = maxbw / minrtt 来收敛就能覆盖各种情况了。参见 拉弗曲线与 BBR 收敛点更合理的 BBR

所以BBR 只是一个单流算法BBR 假设 bw 不再增加且 RTT 开始增加时即到达最佳点但这只是自我视角一旦背景流侵入退出ProbeBBR 的假设几乎全失效完全被吊着走除了 ECN没有任何外部信号指示其收敛BBRv2 好一些响应丢包而限制 inflight_lo但也只是稍微。

BBR 之所以看起来好完全因为人们只关注吞吐而高吞吐则来自 BBR 的大开合行为maxbw-filter 维持 10 roundsminrtt-filter 维持 10s而 maxbwminrtt 均是采集到即生效大开合周期太久以至于对背景流的感知能力及其差BBR 敏感度可谓愚钝级。

论 co-existence 吞吐能力BBR 只比你将 cwnd 单纯调大这种行为好一点点。此外值得一提的是Linux 4.9 以后的内核降低了每个人玩大开合的门槛只要实现 cong_control 回调函数就可以 bypass 几乎所有 Linux TCP 拥塞状态机只需在这个函数里写一句 cwnd = 1000000000000仅以吞吐考量而不论代价你的算法就差不了。

冷眼旁边后对 BBR 再也不是初测时那种认知了甚至没了当初的态度。模型确实勾画出了带宽的正确利用方式但也仅此而已BBR 自身都没能正确使用带宽。BBR 在共存流场景表现非常糟糕其自身并没有内置任何自适应收敛机制且不对外界信号进行即时反馈只会遗忘而遗忘需要时间。在不应该的场合BBR 对丢包又反应过激不过这个我准备单独讨论。总之BBR 不是一个名副其实的好的算法。

浙江温州皮鞋湿下雨进水不会胖。

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6