我写过 TCP\text{TCP}TCP 的性能限制,从公式 T=βRTT1pT=\dfrac{\beta}{RTT}\sqrt{\dfrac{1}{p}}T=RTTβp1 中可见在 AIMD\text{AIMD}AIMD 算法约束下 RTTRTTRTT 和 ppp 对总吞吐的负相关影响,但无论是决定 RTTRTTRTT 的距离还是丢包率下限的介质固有特征,都是外部因素,当理想化外部影响后,限制就没了。
BBR\text{BBR}BBR 便在 ∝1p\propto\sqrt{\dfrac{1}{p}}∝p1 成为带宽限制时被提出,减弱了对丢包的反馈,但由于收敛的最根本目标,逐步又在 v2\text{v2}v2,v3\text{v3}v3 版本恢复了对丢包的反馈。
另一方面,操作系统引入的统计波动的影响也会随着带宽的提升而被放大,总有说法说 CPU\text{CPU}CPU 成了 TCP\text{TCP}TCP 传输的实现瓶颈,但也有多队列,RSS\text{RSS}RSS,TSO/GSO/LRO/GRO\text{TSO/GSO/LRO/GRO}TSO/GSO/LRO/GRO,零拷贝,DPDK/XDP{\text{DPDK/XDP}}DPDK/XDP,BigTCP\text{BigTCP}BigTCP 等 bypass\text{bypass}bypass 技术来应对,绕过操作系统甚至绕过 CPU\text{CPU}CPU。
即便解决了这些外部的瓶颈限制,TCP\text{TCP}TCP 协议有个固有限制永远无法破解,且随着吞吐性能的增加,其影响逐渐加重,从而最终压垮自身。该限制即流式传输。
流式传输意味着总有个位置串行处理每个报文,而在摩尔定律下,串行处理能力属亚线性对数增长,但带宽却是超线性,近乎指数级增长,这个带宽和流式传输的错配限制了 TCP\text{TCP}TCP 的吞吐极限。参考 Amdahl\text{Amdahl}Amdahl 定律对加速比的刻画:
S=1(1−p)+pNS=\dfrac{1}{(1-p)+\dfrac{p}{N}}S=(1−p)+Np1
其中 ppp 是可并行比例,对 TCP\text{TCP}TCP 而言,p=0p=0p=0。
流式传输需要一个虚拟的同步时钟,祸不单行的是 TCP\text{TCP}TCP 以积累确认作为 self-clock\text{self-clock}self-clock,虽然延迟确认,捎带确认,GRO/LRO\text{GRO/LRO}GRO/LRO,帧聚集等技术能尽量压缩 ACK\text{ACK}ACK 小包的数量,但仍存在一个不破坏 self-clock\text{self-clock}self-clock 的极限边界,它随吞吐线性增长。换句话说,吞吐越高,ACK\text{ACK}ACK 小包越多,消耗的单包处理资源越多,最终侵夺掉所有资源。
TCP\text{TCP}TCP 的确认机制加重了串行流的负担,虽然一个载荷报文的长度理论上可以长到一通电话,超线性增长的带宽足以负担足够大的载荷报文,但实际上 000 字节的确认却依然随 BDP\text{BDP}BDP 而不仅是时延而快速增加。
这是《规模:复杂世界的简单法则》描述的克莱伯定律的又一实例。
为什么小包这么厉害,因为再小的包也要 "一趟流程",而每一趟都要一个一个处理,而大包载荷则只需一个包头批处理,利用底层并行资源,"一次性捆绑" 通过。参考高速公路收费员,排列一公里的摩托车和排列一公里的装满摩托车的大挂集装箱卡车,哪个工作更耗时。
流式传输的不可并行化处理,在低时延场景直接抵消了 spraying\text{spraying}spraying,GPU\text{GPU}GPU 的所有收益,这意味着流式传输在 DCN\text{DCN}DCN,AI\text{AI}AI 算力网络的不适应,而在高时延的广域网,QUIC\text{QUIC}QUIC 在端到端传输层面只是另一个更高级的 TCP\text{TCP}TCP,通过加密抵制了协议僵化,从而开辟了更多转发传输的可能,但对拥塞的反应和实际效果,所有流式传输协议都一样。
理论上,流式传输更像沿袭自电话网络,而不是分组交换网,分组交换网从被提出就是 packet-based\text{packet-based}packet-based 的,抵御核打击正需要这种分布式冗余,正是这个原因,才抽象出了沙漏哑铃模型。
在沙漏模型中做流式传输是一种良性的投机,处理好乱序重排即可,但流式传输的低性能并不在传输协议的设计,而在沙漏本身,因为它的腰太细了,太哑了。但总体而言, TCP\text{TCP}TCP 在这个沙漏里的综合表现仍是最优的,注意是综合,而不是性能。
浙江温州皮鞋湿,下雨进水不会胖。