包括BBR在内的所有常见的拥塞控制算法都基于下面的策略:
- 对特定的网络事件实施特定的动作。
比如检测到丢包后窗口减半,RTT变大后排空buffer等等,这些事件和动作的对应关系都是固定的,即便是非拥塞导致的事件,这些算法依然要采取相应的动作。
比如对于CUBIC,即便一个噪声丢包被监测到,窗口依然要降20%,这显然不合理。BBR要好很多,但它还是需要周期性进入ProbeRTT,同时BBR依然对独立丢包事件有所反应,要么这种反应过于保守,要么过于激进,很难兼顾低重传率和高带宽利用率。
互联网本身就是统计复用的,状态特征瞬息万变,事件触发原因错综复杂,根本不存在事件和原因的固定关联,也就不存在事件和动作的固定映射。指望这种固定映射的拥塞控制效果,可想而知。
PCC提出一种持续自学习的方法,不再对特定网络事件作出特定反应,而是将所有回馈数据作为变量交给一个效能函数
U
U
U来处理,效能函数
U
U
U会返回一个得分,分数越高,表明这组数据表征的网络状况越好。只要选择合适的效能函数
U
U
U,PCC便可以同时兼顾高带宽利用率以及高公平性。
我不喜欢把paper重新解释一遍,详情参考:
https://www.usenix.org/system/files/conference/nsdi15/nsdi15-paper-dong.pdf
这里面比较有意思的是如何确定效能函数
U
U
U,简单谈一下我的想法。
效能包括两部分,正效能和负效能,总的效能是两部分相加,如果追求高带宽低时延低丢包,设
T
T
T为测量带宽,
R
T
T
RTT
RTT为时延,
l
o
s
s
loss
loss为当前检测到的丢包,那么效能函数可以表示成:
U
(
T
,
R
T
T
,
l
o
s
s
)
=
f
(
T
)
+
g
(
d
R
T
T
d
t
)
+
k
(
l
o
s
s
)
U(T,RTT,loss)=f(T)+g(\dfrac{dRTT}{dt})+k(loss)
U(T,RTT,loss)=f(T)+g(dtdRTT)+k(loss)
其中:
-
f
(
x
)
f(x)
g
(
x
)
g(x)
k
(
x
)
k(x)
f
(
x
)
f(x)
f(x)和
k
(
x
)
k(x)
k(x)没得说,关键是
g
(
x
)
g(x)
g(x),单纯RTT的绝对值没有意义,因此用RTT的变化作为变量,如果RTT迅速变大,那肯定不是好事,反过来,如果RTT缓慢变小,那肯定是加分项,但加分值显然不如RTT迅速变小。
以上原则保证了每一条PCC流均向最高效能逼近。很神奇的是,所有的PCC流看起来都是自私地逼近自己的最优点,但全局来看,所有的流最终竟然还能收敛到公平,虽然我没有实测这个结论,但这仍然是最吸引我的地方。
现在的问题是,
f
(
x
)
f(x)
f(x),
g
(
x
)
g(x)
g(x),
k
(
x
)
k(x)
k(x)还要满足什么原则,能保证公平性呢?
这是一个复杂的数学问题,但还是可以简单介绍一下基本原理。关键点在于负效能的引入,会对每一次收益扣除相应的代价。
将公平性定义为占用buffer的比例是合理的,在此假设下,从2条流的公平性开始。
如果一条流占据buffer不超过0.5,那么它的正效能将大于负效能,反之如果一条流占据了超过0.5的buffer,那么它的负效能将大于正效能,当正好占据0.5的buffer时,正效能和负效能正好相等,在上述原则约束下,可以绘制出一族满足条件的
U
U
U。显然,如果一条流占据buffer不足0.5时,它倾向于被正效能引导占据更多的buffer,反之则被负效能引导释放更多的buffer,最终两条流各占一半的buffer。
现在推而广之,3条流的
1
3
\dfrac{1}{3}
31占比,4条流的
1
4
\dfrac{1}{4}
41占比…n条流的
1
n
\dfrac{1}{n}
n1占比。只需要在绘制出来的第n族
U
U
U曲线中,找到一条同时最佳拟合所有n族曲线任意一条的曲线即可,其关于
f
(
x
)
f(x)
f(x),
g
(
x
)
g(x)
g(x),
k
(
x
)
k(x)
k(x)的表达式,就是最终的
U
U
U。
假设这个
U
U
U已经存在,实施PCC就变得自然而然。需要做的仅仅是以不同的发送速率不断探测,通过将回馈的结果灌入
U
U
U函数来为该发送速率打分,以此方法慢慢逼近最优发送速率。
PCC paper建议的探测方法是:
- 以
r
1
=
r
(
1
+
ε
)
r_1=r(1+\varepsilon)
r
2
=
r
(
1
−
ε
)
r_2=r(1-\varepsilon)
r
r
ε
\varepsilon
- 获取
r
1
r_1
r
2
r_2
R
1
R_1
R
2
R_2
U
(
R
1
)
U(R_1)
U
(
R
2
)
U(R_2)
- 若
U
(
R
1
)
>
U
(
R
2
)
U(R_1)>U(R_2)
r
=
r
1
r=r_1
r
=
r
2
r=r_2
但这显然不是唯一的方式,如何探测并不是最重要的。
PCC指出了端到端拥塞控制的终极方案,即探测,无论Reno/CUBIC,BBR,还是PCC,事实上都是在探测,Reno/CUBIC以一个AIMD周期来探测,最终探测到一个丢包作为buffer overflow的标志,BBR以8个packet rounds来探测,以获取空余带宽,同时以10s为周期探测以获取RTprop。PCC将所有的这些探测目标体现在单独的一次探测中,所以PCC理论上可以持续学习,以逼近最优解。
无论实际效果如何,PCC是一个新的方向。
BBR通过巧妙分割ProbeBW和ProbeRTT周期以确保探测正交性:
- ProbeBW时,其RTT是RTprop,在up probe造成排队时,drain to target会排出多余的包。
- ProbeRTT时,排空buffer,但max bandwidth依然维持在max-win-filter中。
然而该分割仅针对全网BBR的场景,当面对异构网络与其它CC流共存时,上述的正交性便无法得到保证,10s太久,8个rounds可能也不灵敏,buffer可能并非BBR流填充的,此时如何应对,事情就会变得复杂,BBRv2简直就是妥协的产物,面目已全非。
PCC将正交性融合在了一个单独的效能函数中,每一个round就能获得一个效能结果,事件不会再被探测周期淹没,探测周期可能仅仅为了低通滤波的目的而继续存在。
端到端的拥塞控制,很简单也很难,简单在只需要探测,难在如何探测。
在此前的多年,我和同事一直都在聊如何从一些测量量的导数,二阶导数看到些变化趋势或者可以指导如何反应的实时动态,但并不易,难在实现而不是思路,除了四则混合运算,额外开方,求导,积分,自然对数,这些真的很难,即便是除法,也很难保证精度,我们无法做到快速验证,大多数时候也就只能纸上谈兵了。
浙江温州皮鞋湿,下雨进水不会胖。
原文链接: https://blog.csdn.net/dog250/article/details/120220348
欢迎关注
微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍;
也有高质量的技术群,里面有嵌入式、搜广推等BAT大佬
原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/405687
非原创文章文中已经注明原地址,如有侵权,联系删除
关注公众号【高性能架构探索】,第一时间获取最新文章
转载文章受原作者版权保护。转载请注明原作者出处!