BBR与KCC发送速率调节机制
2026/7/3 3:33:34 网站建设 项目流程

BBR与KCC发送速率调节机制

0. 问题界定

拥塞控制算法的核心输出只有两个变量:Pacing Rate(物理发送速率)CWND(逻辑拥塞窗口)。本文通过源码和可视化图表,剖析 BBR 与 KCC 在决定"下一时刻该发多快"时的核心逻辑。

1. BBR的速率调节:增益表 + inflight门控

BBR 在PROBE_BW(稳态探测)阶段,速率调节依赖一个硬编码的 8 拍增益表bbr_pacing_gain[] = {1.25, 0.75, 1,1,1,1,1,1})。它通过 inflight(在途字节数)判断是否超越物理 BDP,但不直接测量排队延迟。

1.1 BBR的增益控制流程

Phase 0

Phase 1

Phase 2-7

PROBE_BW 周期开始

时钟触发 cycle_idx 切换

pacing_gain = 1.25x (盲测)

pacing_gain = 0.75x (盲排)

pacing_gain = 1.0x (巡航)

满 1 个 min_rtt
AND (丢包 OR inflight >= probe_target)

继续当前 probe 增益

满 1 个 min_rtt
OR inflight <= 1x target

继续当前 drain 增益

满 1 个 min_rtt?

继续当前 cruise 增益

关键点

  • Probe(1.25x)需要同时满足"至少 1 个 min_rtt"和"丢包或 inflight 达标"方可退出
  • Drain(0.75x)可通过inflight ≤ BDP立即短路退出||条件),无需等满 1 个 min_rtt
  • Cruise(1.0x)仅由时钟驱动,必须完成 1 个 min_rtt 才可切换至下一相位

1.2 BBR的数学本质:开环增益调度

BBR 不直接测量T_queue。它写死了 8 个固定增益,靠 inflight 门控探测与排空,辅以丢包/延迟后的被动 TCP 窗口回缩。这在控制论中被归类为开环(Open-loop)预测控制

2. KCC的速率调节:排队测量驱动的闭环修正

KCC 将 BBR 的固定 8 拍增益表扩展为 256 槽位(KCC_GAIN_SLOTS = 256),每槽对应 1 个 RTT 时的增益。默认配置下,增益表结构为:phase 0 = 1.25x(探测),phase 1 = 0.75x(排空),phase 2~(cycle_len-1) = 1.0x(巡航),该模式按cycle_len(默认 = 8)在整个 256 槽表中重复。

KCC 引入卡尔曼滤波器实时估计 T_prop(传播延迟),从qdelay = max(0, RTT_obs − x_est_us)派生瞬时排队延迟,通过 EWMA(默认权重 7/8)平滑为qdelay_avg。速率调节由此变成了受排队测量驱动的自适应边界追踪

2.1 KCC的线性增益衰减

KCC 在探测阶段不盲目执行 1.25x 增益,而是通过排队(qdelay)和抖动(jitter)两项线性且顺序衰减来计算最终增益。衰减仅作用于增益表相位大于 1.0x(BBR_UNIT)的相位:

衰减公式: gain = max(1.0, probe_gain − conf·min(r_q, max_red) − conf·min(r_j, max_red) 顺序扣除)

进入 >1.0x 的增益表相位
(decay_mask 位已置位)

基础增益 = kcc_cycle_gain_table[idx]

计算卡尔曼置信度
conf_scale = (p_max − p_est) × BBR_UNIT / (p_max − converged_val)
未收敛时 conf_scale < BBR_UNIT (衰减折扣)

qdelay 衰减 (预算 max_red):
扣除 min((qdelay_avg − kcc_cong_thresh) × BBR_UNIT / qscale, max_red)
缩放 conf_scale 后从 base_gain 及 max_red 中扣除

jitter 衰减 (剩余预算):
当 max_red > 0 时, 扣除 min((jitter_ewma − kcc_cong_thresh) × BBR_UNIT / jscale, max_red)
缩放 conf_scale 后从 base_gain 中扣除

base_gain 地板 = BBR_UNIT (1.0x)
不会跌破巡航水平

α = BBR_UNIT / qscale (默认 256/20000 ≈ 0.0128/μs)

β = BBR_UNIT / jscale (默认 256/16000 ≈ 0.016/μs)

qdelay 和 jitter 共用同一阈值 kcc_cong_thresh

关键点

  • 非二值开关,而是线性比例衰减r_q ∝ (qdelay_avg − T_cong)r_j ∝ (jitter − T_cong)
  • 顺序扣除而非求和:qdelay 先消耗预算max_red,jitter 再消耗余量;两者各自独立 clamped 在可用预算内,不是min(∑, max_red)
  • 卡尔曼置信度缩放:当p_est > converged_val(未收敛),conf_scale < BBR_UNIT,衰减效果打折——滤波器不确定时不去轻易压制探测增益
  • 增益绝不会跌破 BBR_UNIT(1.0x),即排队再严重也不会把探测降穿到巡航水平

2.2 KCC的Drain-Skip机制

当 KCC 周期轮转到0.75x排空阶段时,可在条件满足时直接将排空转为巡航(“drain-skip”),避免无效的吞吐断崖:

Drain-Skip 三个必要条件

① 卡尔曼已收敛: p_est < converged_val

② 排队低于清洁阈值: qdelay_avg < kcc_clean_thresh

③ 最低驻留: delta > min_rtt / 8

进入 0.75x 排空阶段

等待最低驻留时间
delta > min_rtt >> 3 (min_rtt/8, 防抖动)

全部三个条件?

转换为 1.0x 巡航
(drain-skip 激活)

继续执行 KCC 排空门控
(AND-gate: is_full_length && drained,
+ 4×min_rtt 安全超时)

与 BBR 的关键差异

  • BBR 排空使用OR-gateis_full_length || inflight ≤ BDP,inflight 达标即可立即退出
  • KCC 排空使用AND-gateis_full_length && drained,必须同时满足"满 1 RTT"和"inflight ≤ BDP"才能退出(另加 4×min_rtt 安全超时),这是对 BBRv1 过早退出排空的修复
  • KCC 的 drain-skip 在 AND-gate 之上提供了一条额外的提前退出路径:当卡尔曼收敛且排队低于清洁阈值时,绕开 AND-gate 直接将排空转为巡航

2.3 KCC 与 BBR 控制回路的本质差异

本质差异

KCC: 排队测量驱导

qdelay高

qdelay低 + 已收敛

RTT采样

卡尔曼(估计T_prop)

qdelay = RTT − x_est
EWMA → qdelay_avg

线性衰减 + 卡尔曼置信缩放
floor = 1.0x

drain-skip 跳过排空

发送速率

物理网络缓冲

BBR: 增益调度 + inflight 门控

丢包/延迟

节拍驱动

cycle_idx 索引
bbr_pacing_gain[]

发送速率

物理网络缓冲

被动TCP降窗

增益调度 vs 排队测量驱导

3. 辅助速率调节机制

3.1 PROBE_RTT 机制

两种算法都设有 PROBE_RTT 模式:以极低的 pacing_gain(~0.5x BDP)持续 200ms,强制清空缓冲以测量真实 min_rtt。

  • BBR:每 10 秒固定触发一次,无论路径是否需要。这会产生周期性的吞吐量"断崖"。
  • KCC:引入kcc_probe_rtt_decouple(默认开启)——当卡尔曼滤波器健康(p_est ≤ recal_thresh)时,跳过不必要的 PROBE_RTT,仅在工作状态恶化时才触发。这消除了 BBR 的周期性吞吐断崖。

3.2 ECN 退避与 CWND 增益约束

KCC 在排队压力下同时从两个维度收缩:

  • ECN 退避kcc_ecn_backoff()检测 ECN 标记后,通过factor = (1 − ECN_ratio) × BBR_UNIT降低cwnd_gain,逻辑上相当于在排队超出阈值时收窄拥塞窗口的上限
  • CWND 排队约束kcc_apply_cwnd_constraints()qdelay_avg超过拥塞阈值且不在 PROBE_BW 模式时,缩减cwnd_gain至更保守的水平

这两项机制确保 KCC 在 CWND 维度上同样对排队做出响应,而非仅依赖 pacing_gain。

3.3 算法对比总表

维度BBR(tcp_bbr.cKCC(tcp_kcc.c
增益表固定 8 拍{1.25, 0.75, 1×6}默认 256 槽,pattern 重复(默认cycle_len=8匹配 BBR)
探测衰减 (probe)不衰减,逼满执行 1.25xqdelay/jitter线性衰减+ 卡尔曼置信度缩放,floor = 1.0x
排空退出 (drain)OR-gate:is_full_length || inflight ≤ BDPAND-gate:is_full_length && drained+ 4 RTT 超时
排空跳跃 (drain-skip)卡尔曼收敛 + qdelay < clean_thresh + min_rtt/8 驻留 → 跳过排空
PROBE_RTT每 10s 强制触发卡尔曼健康时跳过,仅异常时触发
ECN / CWND 约束无 ECN 响应ECN 退避降低 cwnd_gain;qdelay 超标时同时压缩 cwnd_gain

4. 结论

BBR 的速率调节是增益表 + inflight 门控bbr_pacing_gain[]提供固定节拍,probe 盲目冲高 (+25%),drain 通过 inflight 短路退出,不直接感知排队深度。

KCC 将 BBR 的框架重构为三层叠加:

  1. 增益表扩展:从 8 拍固定数组到 256 槽可配置表,保留 BBR 兼容默认值
  2. 线性排队衰减gain = max(1.0, probe − conf·min(r_q, budget) − conf·min(r_j, budget)),qdelay 和 jitter 先后消耗预算,衰减受卡尔曼置信度比例缩放
  3. 卡尔曼收敛门控:drain-skip 在 AND-gate 排空之上增加提前跳跃路径;PROBE_RTT 在链路健康时可跳过;ECN/CWND 约束在 qdelay 超标时同步收窄

差异的本质:BBR 在固定节拍和 inflight 门控内寻找边界;KCC 在每个节拍上叠加排队测量的自适应修正——线性衰减(非二值)、顺序消耗预算(非求和)、置信度缩放(非全量门控)。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询