按传统的网络分层模型,传输层做决策,将数据发送到 “系统” 后就不管了,网卡负责实际发送,这保证了传输的可用性,但绝不高效,特别在高速网络场景,这种方式简直是吞吐上不去的根源,上面所谓的 “系统” 受操作系统调度影响,变数实在太大,甚至连高精度时钟都受负载影响而不精确,这部分统计抖动将反噬传输性能。
相反,高速网络传输系统主机延时占比太大,应该由网卡而不是传输层决策,网卡之上提供小 buff 平滑主机系统的统计抖动,传输层只负责收拢数据,保证网卡时刻有数据 pacing 出去。
高速网络传输需颠倒传统网络处理层次,将传输决策下放到数据包离开主机的最后一刻以屏蔽系统抖动,这对网卡提出了非常高的要求。和核心网络只提供高带宽不同,主机网卡在提供高带宽外需处理诸如 sack,cc,flow control 等,因此很贵,而 CPU 反而成了便宜的外设。
25Gbps 网络打 25Gbps 吞吐,每 us 要发出 2 个 1500 字节的数据包,经不起统计抖动(波动这个中性词更合适,但为了突出弊端,使用抖动略带贬义),否则可能面临正反馈衰减,更不必说 100Gbps,400Gbps,800…
无论内核协议栈 or 用户态协议栈,都不是严格实时系统,都是统计复用系统,但凡统计复用就一定会抖动。端主机实现高速网络 pacing 非常难,因为任何抖动将可能引发 pacing 本身正反馈,进一步将衰减放大。
所以,一定不能将系统统计抖动的时间计入传输 RTT 内。为了阐述这一点有多么重要,假设将系统抖动时间计入 RTT,看看会发生什么。
发送期间,如果因系统抖动延迟了几 ns 甚至几 us,这部分时间将被计入 RTT,而一个过大的 RTT 无论对于 delay-based or rate-based 传输协议都会带来一个更小的 cwnd or 更小的 delivery rate,进而主动引入更大的 Pacing 间隔,进入一个正反馈,造成传输吞吐一点点下滑。
作为一个反例,Linux TCP BBR 在尚未引入 internal pacing 时使用 fq 实现 pacing 即如此。彼时 BBR 的 RTT 将 pacing delay 算在了 RTT 内,一个小的抖动极易引发上述正反馈,一直到 pacing delay 的增量与整个 RTT 相比微不足道才停止,幸好 BBR 有主动 probe 机制,但使用 fq pacing,BBR 吞吐很难让人满意。
但 Vegas 没这么幸运。Vegas 没有主动 probe 机制。当系统抖动延时和传输延时数量级,或至少系统抖动延时占比足够高(DC 环境)时,pacing delay 一旦正反馈到 pacing 自身造成吞吐衰减,这种衰减很难快速停止,并最终将吞吐降低到很小的值。
DC 内部,系统抖动引入的延时占比极大,以上正反馈现象更容易发生。根源在统计抖动在闭环中被放大,理论解法,要么拆掉闭环,要么不计入统计抖动。
现实中解决以上问题的方法是在数据包离开网卡的那一刻打时间戳,同时在 receiver 侧网卡收到数据包即计算传输延时,意在将包括 Pacing 间隔在内的主机处理时间完全排除在 RTT 以外。Google Swift 打 4 个时间戳用来细分流程,意思基本就是如此。但显然 TCP 做不到这点。
离开网卡而不是离开传输层打时间戳违背了网络分层原则,但守着这原则又如何呢?如今不引入 hw offloading,都不好意思说自己做过高速网络。
说到底,高速网络的关键就是避开主机端的统计抖动,而硬件离网线足够近,比 CPU 更有能力做到这一点。如果避不开主机侧统计抖动,就一定要把主机一并纳入拥塞控制对象,就像 Swift 那样将 receiver 也视作一个拥塞源。
一个通用的拥塞控制策略应该是:
cwnd = min(win_sndbuff, win_sender, win_transmit, win_receiver, win_rcvbuff);
其中:
win_sndbuff:application 发送缓冲区,覆盖发送程序抖动;
win_sender:传输层至发送网卡的容量,覆盖发送系统抖动;
win_transmit:发送网络经网络到接收网卡的容量,覆盖网络抖动;
win_receiver:接收网卡到传输层的容量,覆盖接收系统抖动;
win_rcvbuff:application 接收缓冲区,覆盖接收程序抖动。
高速网络传输,要排除统计抖动,以确定性替代启发算法:
这趋向于将决策 offloading 到 hw,也确实都想这么做。可 hw 可编程性不如 CPU,无法实现复杂策略,独占 CPU 专核专用,大多数也确实这么做。总之,避开统计复用系统,在这种系统中,再好的调度算法也不足以补偿积累的统计抖动延时。
即使在守恒律的视角,以上观点也合理。任何算法都需要时钟周期,同样的网卡能耗,引入算法必然导致传输能耗的降低,等效于吞吐能耗占比下降。
随着高速网络的迭代,400Gbps,800Gbps 以太网/IB 正当时,1.6Tbps 在路上,CPU 逐渐跟不上,就算 CPU 专核打满也很难满足这么高的带宽,更何况还要处理传输控制等软逻辑,这显然不适合 DC 短肥链路。与长肥广域网不同,这种链路不光漏桶效应不明显而显得吞吐高,传输时延小,系统延时占比也更大,因此需要屏蔽。
浙江温州皮鞋湿,下雨进水不会胖。