BBR 之 cwnd-limited 问题与解法
这问题看起来也不算无解,因为如果有其它流量,比如 AIMD 流共享瓶颈,则 BBR 的 minrtt 本身就是随行 minrtt(本身就包含了 AIMD 的基础 queuing delay) 而非真正的 rtprop,但魔鬼在细节,BBR 保留 minrtt 有 10s 之久,说的就是 cruise 期中的 AIMD 侵入,此态的 BBR 带宽可能由于 cwnd-limited 而持续吃亏 10s
BBR 虽然以 pacing_rate 作为 primary control parameter,但依然保留了 cwnd 作为 secondary control parameter,为了:
Once the pipe is full, the cwnd_gain bounds the queue to (cwnd_gain 1) × BDP
考虑到 delayed ack 以及 stretched ack,默认值为 2,但是 2 是 3 这都不是重点。
理论上,在 cruise cycle 状态下,一个 round 的 quota = delivery_rate * minrtt 刚刚好,但实际上:
- 如果 cycle 期中有新流侵入,则 quato 会造成 queuing;
- 如果 cycle 期中有新带宽空闲,则 quato 会不够。
以上第 2 点可通过等待不超过 CYCLE_LEN 后的 probe 而修正,但对于第 1 点,queuing 可能会加剧拥塞甚至丢包,因此需要通过 cwnd 来 bound。
然而考虑到与非 BBR 流到共存,只要实际的 srtt 大于 cwnd_gain 倍的 minrtt,BBR 将被 cwnd 限制,无数据可发,进入 cwnd-limited 状态。
这问题看起来也不算无解,因为如果有其它流量,比如 AIMD 流共享瓶颈,则 BBR 的 minrtt 本身就是随行 minrtt(本身就包含了 AIMD 的基础 queuing delay) 而非真正的 rtprop,但魔鬼在细节,BBR 保留 minrtt 有 10s 之久,说的就是 cruise 期中的 AIMD 侵入,此态的 BBR 带宽可能由于 cwnd-limited 而持续吃亏 10s 之久,直到获得随行 minrtt = queuing delay + rtprop。
如果采集到 minrtt = 5ms,而突然间遭遇一众新流侵入,rtt 持续进到 50ms,远大于 cwnd_gain = 2 的倍增,cwnd-limited 将 block 掉 sender 到 s 级(多则到 10s)。压力将全部给到 sender,作为一个 streaming system 的应用或服务,block 住任何一个环节,都将造成 bufferbloat 而引入额外时延甚至丢包(block 点前的任何一个环节 buffer overflow 时)。
在 BBR 与 AIMD 公平探究 中,我提到在 ProbeBW 的 pacing_gain = 1 的 cruise cycle 用 (irtt + minrtt) / 2(其中 irtt 为即时 rtt) 计算 BDP 的理由如下:
- cwnd = cwnd_gain * pacing_rate * (minrtt + (irtt - minrtt)/2)
其中 D = (irtt - minrtt)/2 为 queuing delay 的均值,模拟基础 queuing delay,因此算术均值不合适,写成 α * D 则更合理。
如此便可对付 cruise cycle 期中的 cwnd-limited 问题。
今日一想,使用 irtt 似乎并不太妥,这样会放大微突发毛刺,而微突发是禁止随行的,跟随微突发只能雪上加霜,我的目的是与正常 AIMD 和平共处,而非与微突发硬刚。
OK,用 srtt = (1 - β) * srtt + β * irtt 代入 irtt,β 小一些,微突发就被过滤掉了:
- 如果纯 BBR 共存,D = α * (srtt - minrtt)/2 约等于 minrtt;
- 如果 BBR,AIMD 共存,D 随行 AIMD 的 queuing delay 均值(或最小值,调 α 决定);
- 如果 BBR 遭遇微突发,β 越小,低通过滤效果越好;
- 如果还有别的没想到的场景,需要迭代细化 D 模型,增加更多负反馈参数。
你会惊奇发现,在与大而多的 AIMD 流共存时,minrtt 逐渐收敛到 srtt,昨天做了一下模拟,效果非常不错。
解决 cwnd-limited 的常规方法没这么复杂,直接将 cwnd_gain 调大。
bbr3 涉及的一处关于 ProbeBW probe cyccle 的修改我在 BBR cwnd_gain 的循环依赖 中提到过,与本文结合,其实 probe cycle 直接去掉 cwnd_gain 限制,锁定 (1.25X BDP && 不丢包) 即可,但 probe cycle 的 irtt 递增由于自己所为,不能计入 D 等式中的 srtt 计算,因此本文的 srtt 与 TCP 系统实现里的 srtt 并非一回事。
说完了既有 BBR 在 cruise cycle 中途遭遇 AIMD 流的 cwnd-limited 问题,再看既有 AIMD 流共存时,新 BBR 流侵入后如何识别 minrtt 是否真实 rtprop 的问题。虽然这问题并不太影响 BBR 综合性能,但还会影响局部抖动。
这涉及 queuing delay 测量的点是 ProbeRTT 如何做 drain。bbr1 统一缩减到 4 显然激进了,世界上不可能存在一条完全属于 BBR 流的公共链路,且强烈依赖同步。降至 50% * inflt 甚至都过分,理由同上,更简洁明快的表述如下:
- 如果果真只有 BBR 流,降 (1%~5%) * inflt 足以采集到 rtprop,如果只有 1 条 BBR,降 100% 都采不到 rtprop,取折中降 50% 吧。
所有问题几乎都出在适应性上,因此所有解法大多也是针对场景的,或者反过来说也对,因为所有解法都针对场景,所以在适应性上一定会出问题。而适应性需要负反馈就能解决。
在 ProbeRTT 状态降多少 inflt 能采集到良好(不可能无一点噪声的绝对 rtprop)的 minrtt,取决于类似 AIMD 流的 queuing 能力有多强,遇强则强。
设想存在一个单流知道的 rtprop,则 ProbeRTT 采集的 minrtt 与 rtprop 相差越大, 通过降 inflt 采集 minrtt 的效果越差,越没必要降太多,但问题是单流并不知道 rtprop。如果一条 BBR 流上来就进入了 10000 条 AIMD 流共存的 buffer 酱缸内,它能意识到自己采集的 minrtt 是假的 rtprop 吗?
当然能。
通过测量 K = (Δ bw/ Δ Inflt) 即可,如果只有单流,不触顶 K = 1,触顶后 Δ bw = 0,如果多流共存,K < 1,单流份额越小,K 越小,Δ bw 永不为 0。试着增加 1.25X 的 inflt,观察 bw 的增长比例。
据此可以得到一个 ProbeRTT 状态的 inflt 缩减系数 K,K 越大,缩减越多,K 越小缩减越小。
浙江温州皮鞋湿,下雨进水不会胖。
更多推荐
所有评论(0)