从 Kelly-NUM 到时延感知 AIMD 拥塞控制算法

在传输优化领域工作的最后一年写过一类 inflight\text{inflight}inflight 守恒的拥塞控制算法,它完全基于 带宽时延\dfrac{带宽}{时延}时延带宽 做调整,确保低时延,这类算法有一系列实现,我在前年到前段时间陆陆续续展示过几个,有的复杂,有的简单,但本质上它们都是一系列负反馈。

本文从 Kelly-NUM\text{Kelly-NUM}Kelly-NUM 优化的视角完整论述一个 inflight\text{inflight}inflight 守恒算法,以及针对该算法原始实现的一个优化,看看 AIMD\text{AIMD}AIMD 如何将 buffer\text{buffer}buffer 收敛在一个恒值,顺便展示,做一个完整的拥塞控制算法的过程,它远不只是把参数调激进那么简单。

buffer\text{buffer}buffer 收敛的本质是操作点要找对,该操作点是最优的,即 Kleinrock's optimal point\text{Kleinrock's optimal point}Kleinrock's optimal point,于 197919791979 年被提出,被视做膝点,也就是 BBR\text{BBR}BBR 可遇而不可达的点,而此后 Loss-based\text{Loss-based}Loss-based 的 AIMD\text{AIMD}AIMD 工作点被称作崖点。

后来 Jeffrey M. Jaffe\text{Jeffrey M. Jaffe}Jeffrey M. Jaffe 证明,在分布式网络里,各节点只看本地信息无法收敛到这个最优操作点,所以文献里一般不会说实现了 Kleinrock's optimal point\text{Kleinrock's optimal point}Kleinrock's optimal point,我也没有实现,只是逼近,但我的方式显然更漂亮些。

现在基于 NUM\text{NUM}NUM 框架论述它。

原始 Kelly-NUM\text{Kelly-NUM}Kelly-NUM 仅以带宽对数效用度量收益,那是 199019901990 年代,而如今的 online\text{online}online 时代更在意的时延。

换一种度量,即 I=带宽时延I=\dfrac{带宽}{时延}I=时延带宽,从好多年前开始,我基于这个式子做过好几个算法,现在用 NUM\text{NUM}NUM 论证并重构它。

由于 III 无法保证严格凹,需要用一个严格凹的函数等价它的涵义,于是采用:

U=带宽收益−时延惩罚U=带宽收益−时延惩罚U=带宽收益−时延惩罚

在保留凸优化性质的同时引入时延感知:

Ui(x)=log⁡xi−α⋅Di(x)U_i(x) = \log x_i-\alpha \cdot D_i(x)Ui(x)=logxi−α⋅Di(x)

其中 iii 为流 iii 发送速率,log⁡xi\log x_ilogxi 为带宽的效用,对应比例公平的基准,Di(x)D_i(x)Di(x) 为流 iii 的排队时延,α>0\alpha>0α>0 表示时延惩罚权重,调节系统吞吐与时延间的权衡。

设网络有 LLL 条链路,链路 lll 容量 clc_lcl,路由矩阵 Rl,i=1R_{l,i}=1Rl,i=1 表示流 iii 经过链路 lll,链路 lll 总负载 Xl=∑iRl,ixiX_l=\sum_i R_{l,i}x_iXl=∑iRl,ixi,采用 M/M/1\text{M/M/1}M/M/1 模型建模,虽然我知道是不符合现实的,但它简单,时延表示为:

Dl(Xl)=1cl−Xl,Xl<clD_l(X_l) = \dfrac{1}{c_l - X_l},\quad X_l < c_lDl(Xl)=cl−Xl1,Xl<cl

所有流共享排队时延,端到端时延为路径上各链路时延之和。

NUM\text{NUM}NUM 问题可表示为:

max⁡x≥0∑i=1nlog⁡xi−α∑l=1LDl(Xl) s.t.∑iRl,ixi≤cl,∀l\begin{aligned} \max_{\boldsymbol{x}\ge \boldsymbol{0}} \quad & \sum_{i=1}^n \log x_i - \alpha \sum_{l=1}^L D_l(X_l) \ \text{s.t.} \quad & \sum_i R_{l,i}x_i \le c_l,\quad \forall l \end{aligned}x≥0maxi=1∑nlogxi−αl=1∑LDl(Xl) s.t.i∑Rl,ixi≤cl,∀l

∑log⁡xi\sum\log x_i∑logxi 严格凹,Dl(Xl)D_l(X_l)Dl(Xl) 二阶导 Dl′′(Xl)=2(cl−Xl)3>0D_l''(X_l) = \dfrac{2}{(c_l-X_l)^3}>0Dl′′(Xl)=(cl−Xl)32>0,故严格凸,因此目标函数严格凹,约束集 x∣Rx≤c,x≥0x\mid Rx\le c,x\ge 0x∣Rx≤c,x≥0 为线性不等式定义的凸集,凸可行域上最大化严格凹函数,最优解唯一。

引入链路拉格朗日乘子 pl≥0p_l\ge0pl≥0 表示带宽成本,构造函数:

L(x,p)=∑ilog⁡xi−α∑lDl(Xl)+∑lpl(cl−∑iRl,ixi)\mathcal{L}(x,p) = \sum_i \log x_i - \alpha\sum_l D_l(X_l) + \sum_l p_l\left(c_l - \sum_i R_{l,i}x_i\right)L(x,p)=∑ilogxi−α∑lDl(Xl)+∑lpl(cl−∑iRl,ixi)

对 xix_ixi 求偏导并令其为 000,得到一阶最优条件:

1xi∗=∑l:i∈l(pl∗+α⋅Dl′(Xl∗))\dfrac{1}{x_i^*} = \sum_{l: i\in l} \left( p_l^* + \alpha \cdot D_l'(X_l^*) \right)xi∗1=∑l:i∈l(pl∗+α⋅Dl′(Xl∗))

其中 Dl′(Xl)=1(cl−Xl)2D_l'(X_l) = \dfrac{1}{(c_l-X_l)^2}Dl′(Xl)=(cl−Xl)21 为排队时延的边际增量,流 iii 的路径总边际成本由带宽成本和时延边际惩罚组成。

看互补松弛条件:

pl∗⋅(cl−∑iRl,ixi∗)=0,pl∗≥0p_l^* \cdot \left(c_l - \sum_i R_{l,i}x_i^*\right) = 0,\quad p_l^*\ge0pl∗⋅(cl−∑iRl,ixi∗)=0,pl∗≥0

链路未饱和时,∑Rl,i(x)i∗<cl\sum R_{l,i}(\boldsymbol{x})i^* < c_l∑Rl,i(x)i∗<cl,则 pl∗=0p_l^*=0pl∗=0,仅有时延边际代价,而链路饱和时 ∑Rl,i(x)i∗=cl\sum R{l,i}(\boldsymbol{x})_i^* = c_l∑Rl,i(x)i∗=cl,则 pl∗>0p_l^*>0pl∗>0,两个代价共同生效。

最优条件可表述为边际收益等于路径总边际成本。

在单瓶颈场景,所有流共享同一路径成本,故 1xi∗\dfrac{1}{x_i^*}xi∗1 相等,多瓶颈场景则满足广义比例公平,对任意可行扰动 Δx\Delta xΔx,有:

∑iΔxixi∗≤α∑lDl′(Xl∗)ΔXl\sum_i \dfrac{\Delta x_i}{x_i^*} \le \alpha \sum_l D_l'(X_l^*)\Delta X_l∑ixi∗Δxi≤α∑lDl′(Xl∗)ΔXl

公平权重由带宽成本与时延代价共同决定。

现在映射到工程算法。

理想情况下,每条链路维护本地成本 pl+αDl′(Xl)p_l + \alpha D_l'(X_l)pl+αDl′(Xl),并将其标记在数据包中,端侧累加成 Pi=∑l∈i(pl+αDl′)P_i = \sum_{l\in i} (p_l + \alpha D_l')Pi=∑l∈i(pl+αDl′),按 1xi≷Pi\dfrac{1}{x_i}\gtrless P_ixi1≷Pi 执行调整,这严格匹配 KKT\text{KKT}KKT 条件,但哑网络并不支持反馈,无法在互联网部署,但却可以在数据中心自研,就又卷出一篇论文。

仅考虑端到端场景,端侧仅能通过测量可观测值作为等价成本:

  • 丢包事件,对应链路饱和,pl>0p_l>0pl>0,等价带宽成本;
  • 排队时延 Dque=RTT−τpropD_{\text{que}} = \text{RTT} - \tau_{\text{prop}}Dque=RTT−τprop,对应时延边际代价 Dl′D_l'Dl′;

其中 τprop\tau_{\text{prop}}τprop 为传播时延基线。

将其映射为类似 TCP\text{TCP}TCP 的窗口增减机制:

  • 无丢包且排队时延低于阈值,窗口线性增加;
  • 检测到丢包或排队时延超阈值,窗口按比例削减,引入递增惩罚函数 ϕ(Dque)\phi(D_{\text{que}})ϕ(Dque),使惩罚随时延增大而增强,匹配 D′D'D′ 随排队时延上升;

可部署的工程算法如下。

设拥塞窗口 www,速率 x=wRTTx=\dfrac{w}{\text{RTT}}x=RTTw。

加性增触发条件为无丢包,且 Dque<DthD_{\text{que}} < D_{\text{th}}Dque<Dth,更新规则:

w←w+αw \leftarrow w + \alphaw←w+α

乘性减阶段触发条件为检测到丢包,或 Dque≥DthD_{\text{que}} \ge D_{\text{th}}Dque≥Dth,更新规则:

w←w⋅11+β⋅DqueDthw \leftarrow w \cdot \dfrac{1}{1 + \beta \cdot \dfrac{D_{\text{que}}}{D_{\text{th}}}}w←w⋅1+β⋅DthDque1

其中 α,β\alpha,\betaα,β 为 AIMD\text{AIMD}AIMD 参数,DthD_{\text{th}}Dth 为拥塞时延阈值,DqueDth\dfrac{D_{\text{que}}}{D_{\text{th}}}DthDque 为归一化时延,作为递增惩罚函数,时延越高,分母越大,窗口削减越多,以对应 D′D'D′ 随排队时延快速上升:

{Dque=1c−X,Dl′(Xl)=1(cl−Xl)2⟹D′=Dque 2\left\{\begin{aligned}D_{\text{que}} &= \frac{1}{c-X}, \\D_l'(X_l) &= \frac{1}{(c_l-X_l)^2}\end{aligned} \right.\quad\Longrightarrow\quad D' = D_{\text{que}}^{\,2}⎩ ⎨ ⎧DqueDl′(Xl)=c−X1,=(cl−Xl)21⟹D′=Dque2

伪代码如下:

txt 复制代码
# ==============================================
# 算法:Delay-Aware AIMD (DA-AIMD)
# 基于路线 A NUM 模型的端到端拥塞控制
# ==============================================
# 配置参数
#   a:              加性增窗步长
#   beta:           基础衰减系数
#   D_th:           排队时延拥塞阈值
#   w_min, w_max:   拥塞窗口上下限
# 状态变量
#   w:              当前拥塞窗口
#   RTT_smoothed:   平滑后的往返时延
#   min_RTT:        观测到的最小 RTT
#   loss_detected:  当前周期是否检测到丢包

# 初始化
w ← w_init
RTT_smoothed ← 初始测量RTT
min_RTT ← RTT_smoothed
loss_detected ← False

while True:
    发送窗口内数据包,接收ACK
    测量当前样本RTT_sample
    min_RTT ← min(min_RTT, RTT_sample)
    RTT_smoothed ← 平滑滤波(RTT_smoothed, RTT_sample)
    D_que ← RTT_smoothed - min_RTT  # 计算排队时延
    检测当前周期是否出现丢包 → loss_detected

    if loss_detected == False and D_que < D_th:
        w ← w + a
    else:
        penalty_ratio ← 1 + beta * (D_que / D_th)
        w ← w / penalty_ratio
        loss_detected ← False  # 重置丢包标记

    w ← clamp(w, w_min, w_max)

算法完成,但仿真效果不好,究其原因,源自 M/M/1\text{M/M/1}M/M/1 模型中带宽录用率和时延是一对矛盾:

Dque=1C−XD_{\text{que}} = \dfrac{1}{C - X}Dque=C−X1

其中 CCC 是链路容量,XXX 是入速率。

要让 DqueD_{\text{que}}Dque 收敛到一个小值 DtargetD_{\text{target}}Dtarget,C−XC-XC−X 就收敛到固定大值,总速率 X=C−1DtargetX = C-\dfrac{1}{D_{\text{target}}}X=C−Dtarget1 必然小,若想 XXX 逼近 CCC,则 C−X→0C-X\to 0C−X→0,则 Dque→∞D_{\text{que}}\to\inftyDque→∞,时延会随负载指数增加,低时延稳定和满带宽利用率,在排队系统中天然矛盾。

盯着 I=带宽时延I=\dfrac{带宽}{时延}I=时延带宽,为表达它,不纠结形式,只有修改 UUU:

Ui(xi)=log⁡xi−α⋅max⁡(0, Dque(X)−Dtarget)2U_i(x_i) = \log x_i - \alpha \cdot \max\left(0,\ D_{\text{que}}(X) - D_{\text{target}}\right)^2Ui(xi)=logxi−α⋅max(0, Dque(X)−Dtarget)2

其中 X=∑jxjX = \sum_j x_jX=∑jxj 是链路总速率,仍基于 M/M/1\text{M/M/1}M/M/1 建模,Dque(X)D_{\text{que}}(X)Dque(X) 是总速率的单调凸函数。

对 xix_ixi 求导,得到边际效用:

dUidxi=1xi⏟带宽边际收益−2α⋅max⁡(0, Dque−Dtarget)⋅Dque′(X)⏟时延边际代价\dfrac{\text{d}U_i}{\text{d}x_i} = \underbrace{\dfrac{1}{x_i}}{\text{带宽边际收益}} - \underbrace{2\alpha \cdot \max\left(0,\ D{\text{que}} - D_{\text{target}}\right) \cdot D'{\text{que}}(X)}{\text{时延边际代价}}dxidUi=带宽边际收益 xi1−时延边际代价 2α⋅max(0, Dque−Dtarget)⋅Dque′(X)

其中 Dque′(X)D'_{\text{que}}(X)Dque′(X) 是排队时延对总速率的导数,代表速率增加一点,时延上涨的幅度。

最优均衡条件:

dUidxi=0\dfrac{\text{d}U_i}{\text{d}x_i}=0dxidUi=0

欲达此处,最大化效用采用梯度上升准则,即速率变化率与边际效用成正比:

dxidt=k⋅dUidxi\dfrac{\text{d}x_i}{\text{d}t} = k \cdot \dfrac{\text{d}U_i}{\text{d}x_i}dtdxi=k⋅dxidUi

k>0k>0k>0 是步长系数。

代入边际效用表达式,就对应算法的两个分支,当 Dque≤DtargetD_{\text{que}} \le D_{\text{target}}Dque≤Dtarget,max⁡(0,⋅)=0\max(0,\cdot)=0max(0,⋅)=0,惩罚项消失,边际效用 1xi>0\dfrac{1}{x_i}>0xi1>0,速率可持续减缓上升:

dxidt=kxi\dfrac{\text{d}x_i}{\text{d}t} = \dfrac{k}{x_i}dtdxi=xik

当 Dque>DtargetD_{\text{que}} > D_{\text{target}}Dque>Dtarget,惩罚项生效,边际成本随超调量快速上升,当超调足够大,边际成本超过边际收益,边际净效用变负,速率开始下降:

dxidt=k(1xi−2α⋅(Dque−Dtarget)⋅Dque′(X))\dfrac{\text{d}x_i}{\text{d}t} = k\left(\dfrac{1}{x_i} - 2\alpha \cdot (D_{\text{que}}-D_{\text{target}}) \cdot D'_{\text{que}}(X) \right)dtdxi=k(xi1−2α⋅(Dque−Dtarget)⋅Dque′(X))

每个 RTT\text{RTT}RTT 更新一次窗口 www,结合 xi=wiRTTx_i=\dfrac{w_i}{\text{RTT}}xi=RTTwi,将连续微分近似为单步差分,就得到算法的规则。

归一化时延误差来近似调整强度:

e=Dque−DtargetDtargete=\dfrac{D_{\text{que}}-D_{\text{target}}}{D_{\text{target}}}e=DtargetDque−Dtarget

DqueD_{\text{que}}Dque 越低,eee 越负,1−e1-e1−e 越大,增窗越大,对应低时延的激进带宽探测,但接近目标时 e→0e\to0e→0,增窗步长收敛到基准值 α\alphaα,对应算法步骤的增窗:

w←w+a⋅(1−e)⋅RTTRTTbasew \leftarrow w + a \cdot (1-e) \cdot \dfrac{\text{RTT}}{\text{RTT}_{\text{base}}}w←w+a⋅(1−e)⋅RTTbaseRTT

若 e>0e>0e>0,边际代价随超调量 Dque−DtargetD_{\text{que}}-D_{\text{target}}Dque−Dtarget 递增,减窗幅度与超调量成正比,连续负梯度对应离散乘性衰减:

w←w⋅(1−β⋅min⁡(e,1))w \leftarrow w \cdot (1-\beta \cdot \min(e, 1))w←w⋅(1−β⋅min(e,1))

超调量越大,边际惩罚上升越快,减窗越狠。

伪代码如下:

txt 复制代码
# ==============================================
# 算法:FP-DTA-AIMD
# 基于严格凹 NUM 框架,兼顾时延定值与比例公平
# ==============================================
# 配置参数
#   a:              基准增窗步长
#   beta:           超调衰减增益
#   D_target:       目标排队时延
#   RTT_base:       基准 RTT,用于归一化
#   w_slow:         新流加速阈值
#   w_min, w_max:   窗口上下限

w ← w_init
RTT_smoothed ← 初始测量值
min_RTT ← RTT_smoothed
loss_detected ← False

while True:
    min_RTT ← min(min_RTT, RTT_sample)
    RTT_smoothed ← 平滑滤波(RTT_smoothed, RTT_sample)
    D_que ← RTT_smoothed - min_RTT
    e ← (D_que - D_target) / D_target
    检测丢包 → loss_detected

    if loss_detected: # TODO 1
        w ← w * 0.5
        loss_detected ← False
    else if e <= 0:
        increment ← a * (1 - e) * (RTT_smoothed / RTT_base)
        if w < w_slow and D_que < 0.5 * D_target:
            increment ← increment * 2   # 新流加速 TODO
        w ← w + increment
    else:
        penalty ← beta * min(e, 1.0)
        w ← w * (1 - penalty)
        
    w ← clamp(w, w_min, w_max)

裤衩子锁着边儿,而且绣着花儿。

仿真效果图,以下三组分别使用了不同参数,可见一个真矛盾,收敛速度,时延,带宽利用率之间又形成一个不可能三角,可取舍择优,但不可兼得:

挺好的,但相比标准 Loss-based AIMD\text{Loss-based AIMD}Loss-based AIMD 也确实更复杂。

在并不 care\text{care}care 低时延的 offline\text{offline}offline 时代,下载快才重要,选择崖点做操作点就是最优的,只需要 111 个 bit\text{bit}bit 信息就完美收敛,没有比这更极简的了,而当年如果 Delya-based Vegas\text{Delya-based Vegas}Delya-based Vegas 再稍微复杂一点,加点梯度强度而不是分区调整, 便就是本文如此了。

值得一提的是,本文的算法步骤一定要连续,不能分区,否则会破坏 NUM\text{NUM}NUM 推导过程的连续性假设,偏离了 NUM\text{NUM}NUM 框架严格的对偶梯度迭代结构。非连续的分区破坏了所有流按统一边际准则调整速率的公平性基础,导致公平性问题。

时间来到 201020102010 年代,移动设备促进的低存储 onlineonlineonline 时代让低时延变得重要,而不再是大设备大存储的下载,而经理们还在学术区分拥塞控制的类型,实际上不同的算法只是操作点的转移,哪个更加重要而已,经理拿崖点开刀,优化低时延,终究徒劳。

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

相关推荐
网络小江1 小时前
组网第27课:ARP 的能与不能——免费 ARP、代理 ARP 与 ARP 欺骗
服务器·网络·网络安全·负载均衡·免费arp
FY@-@1 小时前
VMware ESXi 7.0 实验全记录:嵌套安装 → 网络配置 → 存储 → Windows 10 虚拟机部署
运维·网络·windows·云计算
ynchyong2 小时前
IPv4 时代的地址冲突检测
网络·ipv4·冲突检测·免费arp·无敌apr·announcemnet
ONLYOFFICE2 小时前
ONLYOFFICE 10.0:深入了解最新的 40 项安全修复
网络·安全
上海云盾-高防顾问2 小时前
边缘验签是什么
运维·服务器·网络
CH_Qing2 小时前
lspci 常见debug 命令
网络
天南散修3 小时前
《802.11-2024》第08讲 · 聚合与块确认:把「一次一帧」变成「一次一批」
linux·网络·wifi·802.11
企业解惑小能手-域智盾系统3 小时前
终端安全管理软件怎么选?终端安全管理不是“装个客户端”:从底层逻辑看企业怎么选
服务器·网络·安全·域智盾软件
济南凡维3 小时前
智能相机 VS 工业相机:机器视觉选型一次讲透
网络·数码相机·视觉检测