多路径传输宣传的要点之一,带宽资源池化,带宽聚合,带宽资源是池化了,但这一池子带宽太昂贵。本文描述为什么昂贵。
值得强调,多路径传输的另一个宣传要点,active-standby 模式路径备份对维持传输的稳定性是极其重要的,好东西不需要多讲,直接体验就好了。
破除带宽聚合的神话,简单说还是《人月神话》里讲的那个简单道理,但技术人并不接受这种叙事方式,那就换个说法。
网络传输关注的是一个 BDP 矩的长宽伸缩,而不是单独的带宽或时延。为理解这个,将填满 BDP 视作目标,B 作为长方形宽度(实则管道横截面积),D 视作长度,BDP 就是面积。即使相同的 BDP,也不意味着相同的行为和约束:
- B 大 D 小意味着要在短时间准备好大量数据填充 B,而 B 小 D 大意味着小量数据 B 要至少持续时间 D;
- B 大 D 也大,相对而言 B 还不够大,D 小的 B 也小,相对而言 B 已足够小,得不偿失,损已致害;
管道要么空载,要么溢出,均带来性能损耗。网络传输性能追求的唯一目标就是数据量的传输总延时最小,同时又不能对数据量做任何约束,简直是个跷跷板。
增加带宽并不一定意味着高效,还要保证足够的数据时刻准备好,如果做不到却又不想付出太大的等待时延,那么高效的网络传输就是要合理安排 BDP 中各自的比例,还是个跷跷板。
现在考虑 MP(MultiPath) 传输,比如 MPTCP,问题可具象成一道应用题:
- 从起点 S 到终点 D 一共有 m m m 条路,每条路宽度分别为 b 1 b_1 b1, b 2 b_2 b2,…, b m b_m bm 个单位,长度分别为 d 1 d_1 d1, d 2 d_2 d2,…, d m d_m dm 个单位,货物以匀速 1 通过这些道路,每件货物占用 1 个单位,现有一批货物总量为 K K K,问如何安排货物经过的路径,使这批货全部从 S 到达 D 的总时间最短。
合理安排路径,若要结局最好,是个熵减过程,总要费点劲,不可能自然而然,这就是调度算法的要旨。
这不是一个容易解决的问题,它不是一个 B 和 D 之间简单调配的问题,而是如何为每一个数据包选择一条路径的问题,BDP 调配成了手段,而非目的。
显然无法用 B 或 D 任何一项排序路径的优良度,原因文初已说过。用 B / D 衡量路径性价比(记做 P)是高尚的。但性价比会随着路径的拥塞而变低,因此性价比是动态的,D 是变化的,它应该表示为 P = B I n f l t B = B 2 I n f l t P=\dfrac{B}{\frac{\mathrm{Inflt}}{B}}=\dfrac{B^2}{\mathrm{Inflt}} P=BInfltB=InfltB2,按这个排序即可。值得注意,B 是需要测量出来的,而 Inflt 已知。
两个数量,相乘为矩,相除为性价比,图一个最优性价比,这个矩形有意思的点就在这。
无论如何都可以直观理解这个算法:
这是一个典型的扩展性问题,典型在先横向扩展,再纵向扩展。世间的例子就是人们居住了几千年的城市。
土地足够,没人想住高楼,城市总先横向扩展,当面积大到当前交通一小时可达圈外,出行成本增加,城区开始增加高度以承载更多组织复杂性,就像一个矩形,先增加宽度以增加面积,触墙后增加高度亦可继续增加面积,但在触墙那一刻的面积已达最佳性价比,再增高就消耗却无益了,所以高楼要么图个摩登,因为古代没有高层技术,要么图个景观,因为看得更远,这便是用技术的高价购置景观的性能了。
再说 MPTCP 带宽聚合时就容易理解其中对错了。若有一条 100Mbps/10ms 链路和一条 50Mbps/100ms 链路,你希望它们聚合到 150Mbps 吗?
当完整聚合到 150Mbps,意味着两条路径的终点有持续流量流出,横截面不多不少 150Mbps,但这意味着两条链路起点处需要更大的 buffer 容纳背靠背流量,具体参考上图最下面自己计算,它一定不是个小数目,你必须准备好那么多数据等待调度。
按端到端观点,从数据生产端积累这么多数据只为填充多路径聚合带宽,这一定要时延做代价,结局是,除了典型下载场景,聚合带宽几乎无益,特别在路径 RTT 差异很大时,值得注意,带宽不是 QoE,但时延是。又值得注意,随着带宽提高,又有多少真正需要下载的场景(多久没有下载电影了?)呢?
背后透视的是作为两极的网络和存储,如果将存储 BDP 当做 0·∞ 的话。
综合来说 MP 协议的意义,其 active-standby 意义大于性能聚合,因为性能只能掣肘,根本无法聚合,这是个简单的道理,正如 KaTeX parse error: Unexpected end of input in a macro argument, expected '}' at end of input: …{2}<\mathrm{big 一样。
如前文所述,带宽聚合的代价是时延膨胀,而时延膨胀是性能劣化的标志,在形而上意义上,你在努力构建一个低熵结构,带宽聚合和时延膨胀的兑换比远不是 1:1,增加一个单位的聚合带宽,远不止付出一个单位的时延,固有的损耗由调度算法引入。
有两条路径参与 MP 协议传输,假设 R T T p a t h 1 , R T T p a t h 2 \mathrm{RTT_{\mathrm{path1}}},\mathrm{RTT_{\mathrm{path2}}} RTTpath1,RTTpath2 随机波动, 我分类讨论 MP 协议聚合模式(active-active)为什么没有意义:
- 小数据量,Inflight 不足,低时延体验优化场景。基于端到端信息度量测不准的本质,调度算法总有机会将数据送入错误(比如 RTT 更大)的路径,引入的时延总和单调递增:
- 如果你有一条时延很低的路径,加入一条时延更大的路径会劣化低时延体验;
- 如果你加入一条时延更低的路径,何不断开当前时延更好的路径;
- 数据量足够,Inflight 充足,高吞吐体验场景。基于端到端信息度量测不准的本质,调度算法错将数据送入更快路径,追不回时间,错将数据送入更慢路径,累计 HoL 等待时延单调递增:
- 如果你有多条路径,由于你有足够数据量,分割数据分别传输可消除调度算法损耗,提高全局性能;
- RFC6356 明确禁止全聚合带宽,即使你实现了理想,也无法发论文,更别谈标准化;
最后,如果非要用 MPTCP 以提高性能,说一个关于 MPTCP 针对 subflow 做 small queue 的实现问题,我的意思是,MPTCP 反而不能对 subflow 做 small queue 约束,如上图最下面,因为 queue 本身就是调度策略基础设施的一部分,Linux 自带的 MPTCPv1 调度以及 MPBBR 也是这么个想法。
近年近月近期,好多关于 MPTCP 优化的东西纷至沓来,我自己也有幸参与其中,本着做什么喷什么的原则,必然要泼点凉水了。
浙江温州皮鞋湿,下雨进水不会胖。