BBR 的 RTT 公平性问题求解

如果 BBR 要跟 reno/cubic 公平,只能顾此失彼,没有任何变通方法,唯一的方法就是在放弃 reno/cubic,但前提你得保证 BBR 流之间是公平的。如果非要照顾 reno/cubic,那就必须要变成 reno/cubic,这就是 BBRv2/v3,但还是变得不够彻底,只能放弃,退而求 BBR 流自身之间的公平,本文就谈这个。而 BBR 自身的公平性问题,就是其 RTT 不公平。

节前最后工作日,一定要有解决这问题的思路才能吃顿烤鱼。

如何解决 BBRv2/v3 的 RTT 不公平问题,此前我一直的想法都是调整 gain,现在看来这是多么肤浅。真正的解法只要解除主要绳结,关注主要矛盾,别的次要问题自然而然化解。

可以明确,根据与 minrtt 负相关定性调整 gain 并不能获得定量公平,无非是让 RTT 小的流获得更大的 gain,而 RTT 大的流获得更小的 gain。具体来讲,可以一如既往地设计一个 sigmoid 函数,单调递减,定义域为 minrtt,取闭区间 [5ms, 100ms],值域为 gain,取闭区间 [1.18, 1.28],当然,还可以更简单地预处理查表,双斜率线性均可,唯一的要点是:

  • RTT 越小,gain 增加的越慢,RTT 越大,gain 下降的越快,背后逻辑是 RTT 越大,BDP 矩越大,越容易产生队列,而 BBR 承诺抵抗队列。

但 gain 的范围如何界定?gain_max 和 gain_min 差异过小(如 [1.20, 1.25]),不足以展开收敛动态范围(没地方折腾就结束了),差异过大(如 [1.05, 1.50]),过大的 gain 会带来突发,产生队列,它甚至都不能缓解 RTT 不公平性问题,何谈解决。

OK,此路不通,那现在说高尚的定量做法。回想起 TCP Prague,就有了答案。

回到 BDP 矢量矩的概念,它是一个符合交换律的乘积,而 BBR 测量正交量种 maxbw 最为目标起作用,因此可将 gain 与 minrtt 结合重构 BDP 矢量矩:BDP = maxbw · (gain · minrtt),在流间公平时,maxbw 相等,gain · minrtt 亦要相等,因此根据 gain · minrtt 固定 gain 缩放 Probe 时间或者固定 minrtt 缩放 gain 就是我们直面选择的。

为达到目标,必须引入一个典型 minrtt 作为参照基准 M,比如若部署在广域网,即可引入国内典型 rtt 中位数,设 M = 25ms 做基准。

再次否定固定 minrtt 缩放 gain,因为若 1.25 · 25 = g · minrtt,g = 6.25 / minrtt。显然 g 会随着做分母的 minrtt 而大幅波动,g 作为 BDP 的倍数,一次性注入 pipe 的 inflight 的动作潜在助长了队列,而队列正是 BBR 所要极力消除的。gain = 1.25 附近刚刚好,永远不要试图通过大幅改变 gain 来优化算法行为,无论吞吐还是公平性。

所以必须走向另一种缩放方案,固定 gain 而缩放 Probe 时间。

现在的目标是让不同 minrtt 的流在 gain = 1.25 的柔缓均匀 pacing 下持续不同的时间,使它们 inflight 相等。同样基于 M 做缩放,由于量纲一致,它就是一个简单的线性缩放,在典型 minrtt = M 下,如果流 1 的 minrtt1 是流 2 的 minrtt2 的 m 倍,则它将持续流 2 时间的 1/m,设 probe持续时间为 x,等式是 1.25 · M · M = 1.25 · minrtt1 · x1 = 1.25 · minrtt2 · x2。

修改也简单,针对 BBRv2,也针对 v3,但 v3 修改要多一些:

c 复制代码
bbr->probe_us = calc_probe_time(sk); // probe_us = 1.25 * M / bbr->min_rtt_us
...
if (bbr2_has_elapsed_in_phase(sk, bbr->probe_us) &&
    ...
    is_bw_probe_done = true;

BBRv3 说是修正了 v2 在 ProbeUP 不能探到底的 bug,在 bbr_reset_full_bw(sk) 后重新探测,这导致了它的激进并加剧了 RTT 不公平,又是一起弄巧成拙。因此修正 v2 的手段不是重新探测到 full(探测到吃力),而是严格管理 ProbeUP 期间的 inflight,保持 inflight 公平,就什么都公平了。说白了就是保持 BDP 矩的公平,这是核心。

代码相关还有一点细节。ACK 时钟可能因为 gro,delayed,聚合等因素不稳定,所以借助本地时钟更好一些,代价就是 CPU。

说回正题。就整个算法而言,由于所有流都像 minrtt = M 的流对齐,那么对于 minrtt > M 的流而言,它们探测空闲带宽的速率将变慢,而对于 minrtt < M 的流而言,这个速度将变快。 交易必不可少。

一般情况下,将 M 做参数,在部署时设置是高尚的。在 DCN 场景,M = 50us,跨洋跨洲长传,M = 100ms,诸如此类。当然,一切还是要基于实际测量,通过统计你要部署网络现状的 RTT,绘制出 RTT 分布的 CDF,取斜率最大点做基础典型 RTT 方可定论。

在 ProbeUP pacing_rate = g 之外,Drain pacing_gain = 0.75 照章办事就行,因为 ProbeUP 已经对齐了,Drain phase 自然就已经齐了。核心问题只要确认都不难解决,但找到它很难,一旦核心问题解决,剩下的什么都不改,就自然解决了,否则就会越改越复杂。当事情变得越来越复杂,涉及越来越多时,就停手,大概率就是方向错了。

事实上,我最初仍想缩放 gain,但得知(从社会学)这多么不靠谱后,我发现自己根本就没有理解 BBR 最初的目标,我的魔改,以及其他几乎所有人的魔改行为,完全都跟我一样没有意识到 BBR 到底是什么,到底要解决什么问题。不管怎么说,总容量一定时,RTT 大的流危害大。反之相反。

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

相关推荐
友莘居士32 分钟前
特征工程四-2:使用GridSearchCV 进行超参数网格搜索(Hyperparameter Tuning)的用途
人工智能·机器学习·支持向量机·特征工程
Tisfy1 小时前
LeetCode 1295.统计位数为偶数的数字:模拟
算法·leetcode·题解
新知图书1 小时前
OpenCV的grabCut算法分割图像
人工智能·opencv·计算机视觉
爱学习的capoo1 小时前
在TensorFlow中,`Dense`和`Activation`是深度学习模型构建里常用的层
人工智能·深度学习·tensorflow
aiAIman1 小时前
深度解析Qwen3:性能实测对标Gemini 2.5 Pro?开源大模型新标杆的部署挑战与机遇
人工智能·深度学习·语言模型·开源
LIUDAN'S WORLD1 小时前
第五部分:进阶项目实战
图像处理·人工智能·python·opencv·计算机视觉·目标跟踪
唯鹿1 小时前
AI生成Flutter UI代码实践(一)
人工智能·flutter·ui
jndingxin1 小时前
OpenCV 图形API(76)图像与通道拼接函数-----对输入图像进行归一化操作函数normalize()
人工智能·opencv·计算机视觉
禺垣1 小时前
GBDT算法原理及Python实现
人工智能·python·算法·机器学习·数据挖掘·集成学习
江安的猪猪1 小时前
大连理工大学选修课——机器学习笔记(5):EM&K-Means
笔记·机器学习·kmeans