先说几句车轱辘话,TCP 性能低,所以 RDMA,以太网丢包,所以 PFC,网卡不能太复杂,所以 GBN…
HPC,AI 对吞吐,时延要求非常高,同时需要更多计算资源,而 TCP 处理需要大量计算资源,复杂逻辑意味着高时延,RDMA 旨在将网络逻辑卸载到网卡硬件,解放了 CPU,同时降低了时延。这是伏笔。
InfiniBand 满足 RDMA 的需求,但复杂且昂贵,需要专用 IB 链路层支撑,而 RoCE 旨在普遍的以太网上部署 RDMA,但以太网是有损网络,会拥塞而丢包,丢包重传会增加网卡实现的复杂性同时增加时延,抵消 RDMA 的优势。这是问题。
硬件难以实现复杂的丢包检测和重传机制,因此由网络保证不会丢包,同时网卡以 GBN 兜底,就是 PFC + GBN。这是解法。
看这一路,完全没从第一性原则解决问题,而几乎全是 bugfix 的修补。虽然旨在替换 TCP 的低效并弥补以太网的松散,但根本上还是在学 TCP,学以太网,没新花样。
简单说几个问题。
PFC 阻塞树蔓延。RDMA 网络从一开始可能就没有考虑大规模扩展性,不然不会采用昂贵复杂的 IB,但凡小规模策略扩展到大规模场景,一定会出问题。城邦制度无法统治帝国,因此罗马共和国必须变成罗马帝国。阻塞树一旦蔓延生长,死锁理论上几乎不可避免,概率高低而已。举个最简单的例子,蔓延时间尺度越大,遭遇路由重收敛概率越大,暂时的环路足以让阻塞树成环,锁死整个网络。
于是,又将出现一系列解决死锁的算法,膏药又糊上了一层。
拥塞控制算法受骗。PFC 基于优先级队列 pause 上游,而不是基于流,因此会出现队头阻塞问题,上游受连累的拥塞无关流被阻塞而造成时延增加,端到端拥塞控制算法会因此而受骗,采取措施反制拥塞。另一方面,如果算法没有受骗,不做反制,那么假拥塞也会变成真拥塞,虽然暂时是拥塞无关流,但被 pause 后相当于人为被拥塞。
如何做?只对拥塞源 mark 标记,不 mark 受害流显然不可行,这样会让假拥塞变真,因此只能共克时艰。换个相反的思路,扩展标记状态空间,对受害流 mark 一个不一样的 “受害” 标记,受害 sender 暂时抑制发送,但当拥塞缓解后,马上 undo,而不是真的做拥塞控制。显然这只是我拍脑袋的想法,说到底还是把戏。
…
即便不重构整个网络,只要从本质出发,问题的解法也会比 PFC 更高尚。
不要指望网络无损,因为不丢包不可能,丢包原因又不止拥塞一种,PFC 显然无法覆盖所有场景,问题的核心应集中在丢包恢复,而拥塞控制完全从丢包解耦,拥塞不与丢包关联,自然就是另一个独立问题。
先不管如何实现,丢包检测靠 NACK,拥塞通知靠源抑制,就是非常第一性的做法,其它的或多或少都在学 TCP,而 TCP 的第一代显然是重实现轻设计的 tradeoff。
无论 NACK 还是源抑制都被标准化委员会负面评价过,但这种评价的背后也是基于 tradeoff,足够就是最好。
基于本质去做设计,一切都是自然而然。与 PFC 相比,QCN,DCQCN 就高尚多了,在不增加新机制前提下,提高了信息精度,不要主机计数,交换机直接将计数结果返回,再与此相比,HPCC 显然就有些过头了,因为它祈求的信息过多了,不得不依赖新机制。
说到 NACK,它最初作为 TCP 的备选方案,思想与 TCP 最终确定的积累确认皆然相反,但在争论过程中败下阵来仅因为积累确认实现的简洁和高效,适应了 1970 年代的网络环境,足够就是最好,但还可以更好。自然,有了 NACK 便不需要 GBN(还有个有趣的 GB0),也就没有 SACK 实现复杂的问题了,一个 bitmap 即可丝滑完成整个过程,TTPoE 对此还有更简单的方案。
我们看到,诸多非 TCP 新传输协议都在喷 TCP 的同时又在学 TCP,很少有彻底解决 TCP 问题的。虽然 QUIC 也有诸多限制,但 QUIC 将 packet id 从字节流 sequence 中分离就是一个非常简单但彻底的修改,一下子就解决了重传歧义问题,扫除了大量 TCP 中的启发式把戏,仅仅就是增加了一个字段。
我们或许已经看到,各大厂已经有将 SACK 移植到自研网卡的案例了,这显然还是在学 TCP。
至于源抑制,从交换机引线接入每一个端主机以及其它交换机,单独做带外控制面,这自然而然就是转控分离的 SDN,而源抑制报文只是传输的控制报文的一种。源抑制之所以被负面评价(参见 RFC896 “Congestion Control in IP/TCP Internetworks” Nagle 的评价),核心在于广域网的不确定性和无标准化,然而我们现在设计的是数据中心网络,而非广域网。与此类似,SDN 不适用广域网,也是一样的考虑。
…
再说实现,都砸钱雇人折腾那么大动静了,又是移植又是重构的,拉一个带外控制面很难吗,重新实现一个 NACK 机制很难吗?
总之,以太网是大势所趋,不要试图改变以太网的有损本质,这正是它成功的原因,折腾一圈把以太网变成类 IB,还不如直接用 IB。以太网固然有损,需要主机弥补损失,要做的事情只有两个:
- 减少丢包
- 及时重传
减少丢包的方式分两个方法,用更高质量的设备和线缆,减少误码率,用更大带宽(或更大 buffer 吸收更多 incast?不建议,但赞成)的设备配合源抑制,减少拥塞丢包,而及时重传的方案也没太多花活儿,NACK 足够,但不要猜,如果网络丢包非常罕见,GBN 也不是不可。
此前有朋友问不开启 SACK 的 TCP 能不能做 RACK,这问题拧巴了,但世上大部分问题都是让你知其不可为而为之,然后就有了各种把戏方案,这样或那样,类似 pacing 或 burst,你永远把握不好那个 “度”。其实这个问题只要修改 TCP 的一个细节就能解决,让 receiver 回复 ACK 时,timestamp 的 tsecr 永远携带最近收到数据的 tsval 即可,看似解法简单,但谁知道会带来别的什么新问题呢,因为这不是本质。
浙江温州皮鞋湿,下雨进水不会胖。