多路径 bbr mpbbr 公平性推演

mptcp 推出很久了,先看 rfc6356 三原则:

  • 对自己,mptcp 的吞吐不能比用 sp(single path)tcp 时更差;
  • 对它者,mptcp 子流对资源的占用不能侵害其它 sptcp 流量;
  • 负载分担,要将孬 subflow 流量分担到好 subflow 上。

若精心实现这三者,过犹不及:

  • 负载均匀分担到所有 subflow 需精确计算,但 tcp 的信息精度不支持;
  • 目标执着于 mp,有时吞吐还不如 sp,且乱序,重传导致时延增加;
  • 挑选最优路径,意味着次优等其它路径被放弃;

这些问题本质原因还是 tcp 乃至所有传输层协议信息精度不足以支撑 mp 传输,我认可 mp,但我不认可 mptcp。

说到底就是 tcp/ip 网络传输缺乏一种模糊逻辑和概率路由的机制,这一点我在前面谈到图论最大流最小割时有说过,若 ip 路由不以最短路径为基,而以排序最小割最大流为概率进行传输,网络天然就 mp,其上的 tcp 天然就 mp,若有一日有人发现最短路径可解放保序业务主机算力,那他会提出 sptcp,即单路径 tcp 协议,也能有一篇论文当经理。事情正反都合理,事情正着做,逻辑要反着想。

说说 mpbbr。

昨天有朋友问我 bbr 多路径问题,如果每条 subflow 都跑 bbr,n 条子流就是 n 倍嗨,这违反 rfc6356 原则二。我就着这问题简单推演了一个 bbr 的多路径模型。

先提出问题,然后推演模型,再然后调参,最后仿真,最最后上线灰度,但显然最最后也没得机会。

mptcp 拥塞控制核心是耦合,即所有子流不再独立进行拥塞控制,而彼此影响,比如在控制 cwnd 总量的前提下针对性调整某条子流的 cwnd。这在 aimd 算法中很容易实现,当前主流 mptcp 拥塞控制的耦合算法基本都是 aimd,不再赘述。但对 bbr 而言,由于它是 rate-based,而 rate 作为矢量不存在耦合,便无法采用 aimd 的方法,便需要一个新方法来保证 mpbbr 不侵害其它 sptcp 流量。

何谈侵害?有交互才能侵害,如果两个流量走不同路径便井水不犯河水谈不上侵害,因此只有经过相同瓶颈的流量才需要确保公平性,mptcp 也不例外。

bbr subflow 共享瓶颈识别非常简单,同步 probertt 意味着同时进入 probertt 的 subflow 共享瓶颈,同时还可辅助一些别的手段加以确认减少误判,比如单独 subflow probe 时 rtt 同时升高的 subflow 共享瓶颈,将共享瓶颈的 subflow 们加入集合 S,目标是 “集合 S 内的所有 subflow 不能联合起来侵害共享同一瓶颈的其它 sptcp 流”

由于 bbr 独立测量 maxbw 和 minrtt,若不对这个过程加以干涉,bbr 默认会独自与其它流共享资源,将它们耦合在一起的方式就是提供一个作用力,让集合 S 中的 subflow 们一起往里收,最终每个 subflow 收到 1 / n 的力道。

先看标准 bbr 的动力学方程,以 3 条流为例:

d x d t = C ⋅ g ⋅ x ⋅ R g ⋅ x ⋅ R + y ⋅ R + z ⋅ R − x \dfrac{dx}{dt}=C\cdot \dfrac{g\cdot x\cdot R}{g\cdot x\cdot R+y\cdot R+z\cdot R}-x dtdx=CgxR+yR+zRgxRx

y d t = C ⋅ g ⋅ y ⋅ R g ⋅ y ⋅ R + x ⋅ R + z ⋅ R − y \dfrac{y}{dt}=C\cdot \dfrac{g\cdot y\cdot R}{g\cdot y\cdot R+x\cdot R+z\cdot R}-y dty=CgyR+xR+zRgyRy

z d t = C ⋅ g ⋅ z ⋅ R g ⋅ z ⋅ R + x ⋅ R + y ⋅ R − z \dfrac{z}{dt}=C\cdot \dfrac{g\cdot z\cdot R}{g\cdot z\cdot R+x\cdot R+y\cdot R}-z dtz=CgzR+xR+yRgzRz

我以 probe 之后为收力点,若 probe 到带宽 c,我将其缩放为 c = c * (1/c),缩放系数为 d = 1 / n,即在上面方程组右边第一项后面再乘以一个系数 d 即可。

若设计独立的拥塞控制算法,公平性最大的难点在于共享瓶颈的流量彼此独立互不知情,我经常卡顿于不知道 n 的尴尬,若知道了 n,一切就迎刃而解。幸运的是 mpbbr 中,sender 知道 n,知道集合 S 的一切信息。

但事情并没有这么简单。如果某条流直接缩放 1 / n,腾出的资源会被同在 S 中的其它 subflow 拿去,公平性动力会浪费在 subflow 彼此交互之上,因此需要走 “绝对值越小加速比越大” 的路子,即选择系数 d > 1 / n。或另一个路子,分批次慢缩放。

微分方程改为下:

d x d t = C ⋅ g ⋅ x ⋅ R g ⋅ x ⋅ R + y ⋅ R + z ⋅ R ⋅ D − x \dfrac{dx}{dt}=C\cdot \dfrac{g\cdot x\cdot R}{g\cdot x\cdot R+y\cdot R+z\cdot R}\cdot D-x dtdx=CgxR+yR+zRgxRDx【D > 1 / n】

接下来模拟调参。先给出下面的数值解:

a, b = 1.25, 0
C, R = 20, 0.1
x0, y0, z0, w0, q0, k0 = 1, 3, 5, 8, 9, 2
u0 = 0
T, dt = 380, 0.01
...
# 调节 b
b =...
for n in range(1, len(times)):
    x[n] = x[n-1] + dt * (C*a*R*x[n-1]/(R*(k[n-1] + a*x[n-1] + y[n-1] + z[n-1] + w[n-1] + q[n-1]))*b - x[n-1])
    y[n] = y[n-1] + dt * (C*a*R*y[n-1]/(R*(k[n-1] + a*y[n-1] + x[n-1] + z[n-1] + w[n-1] + q[n-1]))*b - y[n-1])
    z[n] = z[n-1] + dt * (C*a*R*z[n-1]/(R*(k[n-1] + a*z[n-1] + x[n-1] + y[n-1] + w[n-1] + q[n-1]))*b - z[n-1])
    w[n] = w[n-1] + dt * (C*a*R*w[n-1]/(R*(k[n-1] + a*w[n-1] + x[n-1] + y[n-1] + z[n-1] + q[n-1]))*b - w[n-1])
    q[n] = q[n-1] + dt * (C*a*R*q[n-1]/(R*(k[n-1] + a*q[n-1] + x[n-1] + y[n-1] + z[n-1] + w[n-1]))*b - q[n-1])
    k[n] = k[n-1] + dt * (C*a*R*k[n-1]/(R*(q[n-1] + a*k[n-1] + x[n-1] + y[n-1] + z[n-1] + w[n-1])) - k[n-1])

    u[n] = (x[n] + y[n] + z[n] + w[n] + q[n])

集合 S 中有 x,y,z,w,q 一共 5 条 subflow,与共享瓶颈的另一条标准 bbr 流 k 参与公平收敛,目标是 k 线和 u 线重合。为简化调参过程,我用另一种方式模拟 k,即让其固定 inflight-in-buffer。

既然 C * R = 2,若公平共享,k 的 inflight-in-buffer 应为 1,于是用 B = 1 替换 k[…] * R:

x[n] = x[n-1] + dt * (C*a*R*x[n-1]/(B + R*(a*x[n-1] + y[n-1] + z[n-1] + w[n-1] + q[n-1]))*b-x[n-1])
...
k[n] = C*B / (R*(x[n] + y[n] + z[n] + w[n]) + B)

n = 2 时,b = 0.998,n = 5 时,b = 0.911,效果如下:

在这里插入图片描述

这意味着 D 随着 n 的增大在减小,需要设计一个减函数 0 < D(n) <= 1,但这是另一件事,方法也简单,先给出 n = 1,2,3,4,…,m 时得到的最佳 D,然后用一个函数拟合这些点即可,如果要空间换时间,就存储为静态表,以 n 为键查表。

具体到代码的修改,只需要修改一下以下片段:

static const int bbr_pacing_gain[] = {
        BBR_UNIT * 5 / 4,       /* probe for more available bw */
        BBR_UNIT * 3 / 4,       /* drain queue and/or yield bw to other flows */
        BBR_UNIT, BBR_UNIT, BBR_UNIT,   /* cruise at 1.0*bw to utilize pipe, */
        BBR_UNIT, BBR_UNIT, BBR_UNIT    /* without creating excess queue... */
};
...
... D(int n, int idx)
{
    if (idx < 2) return 1;
    ...
}
...
        case BBR_PROBE_BW:
                bbr->pacing_gain = (bbr->lt_use_bw ?
                                    BBR_UNIT :
                                    D(n, bbr->cycle_idx) * bbr_pacing_gain[bbr->cycle_idx]);
                bbr->cwnd_gain   = bbr_cwnd_gain;
                break;

如何将 n 传入 bbr不谈,核心难点是内核中如何处理 0.998,0.827 这种数字。所以我只做了仿真测试,没有真去修改内核的 bbr.c,因为搞不定。至于 bbr3 如何,原理一样。

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

  • 25
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值