TCP UCP v1.0:当 BBRv1 遇上卡尔曼滤波
一、背景
TCP 拥塞控制算法 BBRv1(Bottleneck Bandwidth and RTT)自 2016 年提出以来,因其基于带宽和延迟测量而非丢包的独特思路,在高带宽长距离网络中表现出显著优势。BBRv1 的核心思想是:通过滑动窗口记录最近若干 RTT 样本的最小值作为传播延迟(min_rtt),通过滑动窗口记录带宽最大值作为瓶颈带宽,然后以 BDP 为基准发送数据。
然而,滑动窗口最小 RTT 存在固有局限:窗口长度固定,无法在统计精度与响应速度之间动态平衡;对网络抖动的容忍度较低,一个异常大的 RTT 可能污染窗口,导致 min_rtt 高估,进而使 BDP 偏高,引发不必要的队列堆积。
UCP(Universal Communication Protocol)v1.0 尝试用一种更系统的方法解决这个问题:用卡尔曼滤波器替代滑动窗口最小值来估计传播延迟,同时在 BBRv1 四状态框架内增加了多项自适应机制。本文将根据公开的源代码和设计文档,客观介绍 UCP 的核心思想与技术原理。
二、整体设计思路
UCP v1.0 保留了 BBRv1 的四个状态机:
- STARTUP:指数增长,快速探测带宽。
- DRAIN:排空 STARTUP 中累积的多余队列。
- PROBE_BW:稳态循环探测,增益在 0.75x ~ 1.25x 之间周期性变化。
- PROBE_RTT:周期性降低 inflight,重新测量最小 RTT。
与 BBRv1 的最大差异在于 最小 RTT 估计 。UCP 引入单状态卡尔曼滤波器,将真实传播延迟作为隐藏状态,RTT 测量值作为观测值,通过递推贝叶斯估计在线输出最优估计,替代 BBRv1 的 min_rtt_us 用于 BDP 计算。
三、卡尔曼滤波器设计
3.1 状态空间模型
状态转移(随机游走):x[k] = x[k-1] + w[k], w ~ N(0, Q)
观测方程: z[k] = x[k] + v[k], v ~ N(0, R)
其中:
x:真实传播延迟(微秒 ×kalman_scale,定点缩放)z:观测 RTT(微秒 ×kalman_scale)Q:过程噪声协方差(反映传播延迟的变化幅度)R:测量噪声协方差(反映单次 RTT 测量的不确定性)
3.2 标准递推公式(标量形式)
c
// 预测
x_pred = x_est; // 状态预测(恒等转移)
p_pred = p_est + Q; // 协方差预测
// 更新(获得新测量值 z)
innov = z - x_pred; // 创新值
K = p_pred / (p_pred + R); // 卡尔曼增益
x_est = x_pred + K * innov; // 状态更新
p_est = (1 - K) * p_pred; // 协方差更新
卡尔曼增益 K 决定了滤波器对测量值的信任程度:K 接近 1 时主要信任测量值,K 接近 0 时主要信任预测值。
3.3 自适应机制
UCP 在标准卡尔曼基础上增加了多项自适应,以提高在真实网络环境中的鲁棒性:
| 机制 | 描述 | 代码中的体现 |
|---|---|---|
| 自适应 Q | Q = Q_base × max(q_min_factor, min_rtt_us/1000),路径越长,过程噪声越大。 |
ucp_kalman_update() 中的 Q 计算 |
| 自适应 R | R = R_base + (jitter_ewma - jr_thresh) × R_base / jr_scale,抖动大时降低对测量的信任。 |
同函数中的 R 计算 |
| 异常值门控 | 动态阈值 max(outlier_ms×1000×scale, jitter_ewma×mult×scale),超过阈值且滤波器自信时拒绝样本。 |
创新值绝对值的比较逻辑 |
| 连续拒绝强制接受 | 连续拒绝次数超过限制后,强制接受下一个样本,防止滤波器被锁死。 | consec_reject_cnt 与 ucp_kalman_max_consec_reject |
| Q‑Boost | 创新值极大时重置 p_est = p_est_init,使滤波器快速响应路径变化。 |
abs_innov > q_boost_thresh 时的重置 |
| 协方差匹配噪声估计 | 在线学习 Q 和 R 的估计值(q_est, r_est),与启发式值结合。 |
ucp_kalman_noise_mode 以及 q_est/r_est 的更新 |
四、基于卡尔曼输出的增强机制
卡尔曼滤波器不仅提供 x_est(传播延迟估计),还输出 qdelay_avg(排队延迟 EWMA)和 jitter_ewma(抖动 EWMA)作为辅助信号,用于控制以下行为:
4.1 PROBE_BW 增益衰减
在 PROBE_BW 循环中,对于预设的衰减相位(通过 256 位掩码 ucp_cycle_decay_mask 标记),如果探测增益大于 1.0x,则根据当前的 qdelay_avg 和 jitter_ewma 线性降低增益,下限为 1.0x。公式为:
reduction = min(max(0, qdelay - qdelay_thresh) * BBR_UNIT / qdelay_scale, max_red)
+ min(max(0, jitter - jitter_thresh) * BBR_UNIT / jitter_scale, max_red - qdelay_reduction)
effective_gain = max(probe_gain - reduction, BBR_UNIT)
这意味着当链路已经出现排队或抖动时,UCP 会自动降低探测强度,避免进一步恶化拥塞。
4.2 主动 cwnd 缩减
当卡尔曼滤波器收敛(p_est < converged_p_est)且 qdelay_avg 超过阈值时,主动降低 cwnd_gain(从默认 2.0x 线性降至 0.75x)。缩减幅度与超额排队延迟成正比,在 qdelay 从阈值到 5 倍阈值的区间内线性插值。
4.3 动态 PROBE_RTT 间隔
利用卡尔曼协方差 p_est 的大小作为置信度度量,动态调整 PROBE_RTT 的触发间隔:
p_est ≤ converged_p_est:间隔 =dyn_max_sec(默认 30 秒)p_est ≥ 4×converged_p_est:间隔 =base_sec(默认 10 秒)- 中间区间线性插值
置信度越高(p_est 越小),PROBE_RTT 间隔越长,减少周期性的吞吐损失。
4.4 LT 带宽估计
LT(Long‑Term)带宽是一个独立的保守带宽估计通道。它通过丢包事件触发采样,在连续若干 RTT 内收集数据,如果丢包率超过阈值(新版默认 9.8%),则计算带宽并与历史 LT 带宽比较一致性。一致时更新 lt_bw 并接管发送速率(lt_use_bw = 1),使连接在丢包环境下采用更稳定的速率。经过 lt_bw_max_rtts 个 RTT 后自动重置,重新探测。
五、与 BBRv1 的主要区别总结
| 方面 | BBRv1 | UCP v1.0 |
|---|---|---|
| 最小 RTT 估计 | 滑动窗口最小值 | 卡尔曼滤波(在线最优估计) |
| 对抖动的处理 | 无专门处理,直接进入窗口 | 自适应 R 降低测量信任 + 异常值门控 |
| 对路径变化的响应 | 等待窗口过期 | Q‑Boost 重置协方差,快速收敛 |
| PROBE_RTT 间隔 | 固定 10 秒(长 RTT 减半) | 动态,基于协方差置信度 |
| PROBE_BW 探测强度 | 固定增益循环 | 基于 qdelay/jitter 的增益衰减 |
| cwnd 调整 | 仅按 BDP + 增益 | 额外增加基于 qdelay 的主动缩减 |
| 丢包场景的带宽 | 仍使用 max_bw(可能偏激进) | LT 带宽提供保守估计 |
| ECN 响应 | 无 | 可选的 ECN 回退 |
六、使用与调优
UCP 作为 Linux 内核模块实现,编译后可通过 insmod 或 modprobe 加载。默认算法名为 "ucp",可使用 ip route change default cong ucp 或写入 /proc/sys/net/ipv4/tcp_congestion_control 来启用。
所有模块参数位于 /proc/sys/net/ucp/ 下,分为以下几类:
- PROBE_RTT 间隔 :
ucp_probe_rtt_base_sec、ucp_probe_rtt_dyn_max_sec等。 - 增益参数 :
ucp_cwnd_gain_num/den、ucp_high_gain_num/den、ucp_gain_num[]/den[]等。 - 卡尔曼滤波器 :
ucp_kalman_q、ucp_kalman_r、ucp_kalman_converged_p_est、ucp_kalman_outlier_ms等。 - 增益衰减阈值 :
ucp_qdelay_probe_thresh_us、ucp_jitter_probe_thresh_us。 - LT 带宽 :
ucp_lt_loss_thresh(默认 25)、ucp_lt_intvl_min_rtts等。 - ECN :
ucp_ecn_enable、ucp_ecn_backoff_num/den。
对于普通用户,保持默认值即可工作。对于弱网场景(Wi‑Fi、4G/5G 边缘),建议重点关注:
ucp_lt_loss_thresh = 20~25(已默认 25)ucp_ecn_enable = 1(如果网络支持 ECN)
诊断可通过 ss -i 查看类似 BBR 的输出字段(bbr_min_rtt 实际是卡尔曼估计值)。
七、总结
UCP v1.0 是一个将 BBRv1 状态机与卡尔曼滤波相结合的 TCP 拥塞控制实现。它在保留 BBR 带宽探测框架的同时,用统计信号处理方法改进了传播延迟估计,并引入多项自适应机制。从设计文档和公开的测试数据看,该算法在抖动较大、有一定丢包的网络环境下(如移动网络、无线链路)相对 BBRv1 表现出更低的延迟抖动和更稳定的吞吐。但作为较新的算法,其在超大规模生产环境中的长期表现仍有待验证。对于希望尝试新拥塞控制算法的技术爱好者,UCP 提供了一个值得研究的工程范例。