BBRv2的问题

对ECN信号的响应缓慢且不够有效

这是 BBRv2 最核心的缺陷之一。BBRv2 尝试将 ECN作为避免丢包的早期信号,但其处理方式存在问题。

  • 机制缺陷:BBRv2 收到 ECN-CE(Congestion Experienced)标记后,并不会立即降低其发送速率。相反,它会将 ECN 视为一个信号,表明网络中的队列正在增长,然后它会降低其“探测带宽的上限目标”(即 inflight_hi)。它本质上是说:“我知道网络开始挤了,下次我探测新带宽时会收敛一点。”
  • 导致的问题:这种响应是间接且滞后的。从收到 ECN 信号到 BBRv2 真正减少其飞行数据量(inflight),可能需要等待多个 RTT(往返时间)。在这段时间里,网络中的队列会持续增长,导致延迟大幅上升。这违背了 ECN “在丢包前主动控制队列”的初衷。最终结果是,BBRv2 依然会造成不必要的延迟,只是把部分丢包问题转化为了延迟问题。

在浅缓冲区下的公平性问题依然严重

BBRv2 试图通过对丢包更敏感来改善与 CUBIC 等基于丢包的算法的公平性,但在缓冲区很小的网络设备(如某些家用路由器或数据中心交换机)上,问题依旧。

  • 机制缺陷:BBR 的核心行为之一是通过 pacing_gain > 1(例如 1.25)来主动探测更高带宽。这个行为必然会在瓶颈处建立一个短暂的队列。如果交换机的缓冲区非常小,这个“短暂的队列”会瞬间填满并导致丢包。
  • 导致的问题
    • 对于 CUBIC:CUBIC 看到丢包,会立刻大幅降低其发送速率(乘性减)。
    • 对于 BBRv2:BBRv2 看到由自己探测行为引发的少量丢包,其内部模型可能认为这是可控的,不会像 CUBIC 那样剧烈地减速。
    • 最终结果:在一个丢包频繁的浅缓冲区链路上,CUBIC 会被 BBRv2 严重压制,不断减速,而 BBRv2 则维持一个相对较高的发送速率,最终“饿死”CUBIC 流量,导致严重的带宽不公平

在高丢包率网络中的性能不佳

BBRv2 为了变得更“友好”,对丢包的响应比 BBRv1 敏感得多。但这把双刃剑在无线网络(Wi-Fi, 4G/5G)等天然存在随机丢包(非拥塞导致)的环境中,反而造成了性能下降。

  • 机制缺陷:BBRv2 难以区分“拥塞丢包”和“随机丢包”。当它在无线链路上遇到随机丢包时,其算法模型会错误地判断网络发生了拥塞,从而降低发送速率。
  • 导致的问题:这种不必要的减速导致 BBRv2 在有损网络环境下的吞吐量远低于实际可用带宽。它过于“谨慎”,因为它无法确信丢包不是由自己造成的拥塞引起的。BBRv3 引入“丢包守恒 (Loss Conservation)”原则,正是为了更好地处理这种情况。

算法模型过于复杂

为了解决 BBRv1 的种种问题,BBRv2 引入了大量的启发式规则和内部状态变量(如 inflight_hi, inflight_lo, bw_probe_samples 等)。

  • 机制缺陷:这些复杂的组件相互作用,使得算法的行为在某些边缘情况下变得难以预测和推理。例如,它在判断何时退出 Startup 状态、何时开始带宽探测、以及探测的激进程度等方面,都依赖于一套复杂的逻辑。
  • 导致的问题
    • 行为不稳定:在网络路径特性频繁变化的场景下,BBRv2 的复杂状态机可能做出次优决策。

BBRv3的改进

BBRv3 的目标:

  • 带宽高、延迟低:尽量满用瓶颈带宽,同时队列不长导致延迟爆炸。
  • 公平共存:和传统 loss-based 算法(比如 CUBIC)、不同延迟的流、以及在大 buffer 或小 buffer 环境里,都能较好竞争。
  • 灵敏地对丢包/ECN 信号响应,即 loss/ECN 不再只是“辅助”,而是重要信号,会影响 inflight 上限 。
  • 改进参数设定与状态转换:例如 STARTUP 探测速度、ProbeBW DOWN/UP gain、什么时候退出 UP,怎样设定 inflight_hi/inflight_lo 等上下界,以便让速度/窗口在不同状态中更合理。

BBRv3的实现

STARTUP

  • pacing_rate = 2.77 × bw * (1 − margin) (margin 常设 1%,即 pacing_rate ≈ 0.99 × 2.77 × bw)
  • cwnd_max = cwnd_gain × bdp + extra_acked
  • 当你收到一个 rate sample(rs),更新 bw,如果连续几个 ROUND(若干个 RTT)里 bw 没增加了,就认为“filled the pipe”,退出 startup。
  • 如果丢包率很高(比如在一个 RTT 里丢包超过某个阈值),也可能提前退出。

DRAIN

  • pacing_gain = 0.35 → pacing_rate = 0.35 × bw
  • 继续使用 cwnd_gain = 2.0
  • Monitor in_flight(当前未确认的发送量) 如果 in_flight ≤ bdp(即估计队列已经排完),就退出进入 ProbeBW

ProbeBW

UP

  • 先在 REFILL 阶段做 “reset” 或清除旧的下界 bw_lo/inflight_lo,以便在 UP 阶段允许增长
  • 在 UP 阶段: pacing_gain = 1.25,cwnd_gain = 2.25
  • cwnd_max = cwnd_gain × bdp + extra_acked,(加上 inflight_hi 限制)
  • pacing_rate = 1.25 × bw × (1 − margin)
  • 如果在 UP 阶段发现 loss/ECN 信号超过阈值/bw 没有进一步提升(plateau),就出 UP → 进入 DOWN

DOWN

  • pacing_gain = 0.90,cwnd_gain = 2.0
  • 目的是稍微降低发送率 / in_flight,以给自己和竞争者“喘息”的空间,使队列减少
  • 退出 DOWN 条件:in_flight ≤ bdp 且满足 “free headroom” 的标准(如果 inflight_hi 已设),即不太可能引起队列或者过多排队

PROBE_RTT

  • cwnd_gain = 0.5 → cwnd 降到约 0.5 × bdp + extra_acked 或者最小窗口(如 4 MSS)
  • pacing_gain = 1.0
  • 时间短,只为测一个 RTT 内的基本 min_rtt