接着 现代操作系统和 TCP/IP 继续。
现代分时系统的时间片轮转机制让人们可以 “同时使用计算机”,从而滋生了 “同时使用网络” 的需求,现代分时系统是分组交换网的原动力。
从来没有超过一个人同时使用同一部电话,因此独占线路的电路交换理所当然,但计算机则相反,许多人一起使用计算机,每个人读希望独占通信线路,而分组交换则提供了独占线路的假象,正如时间片轮转提供了独占计算机的假象一样。
可以非常直接地类比时间片轮转的现代分时系统和分组交换网,两者太像了,背后的机制也一样。对于分组交换网,一条数据流被分为若干数据包,多条数据流的所有数据包统计复用网络链路,而对于现代分时系统,一个程序的指令流被分隔在不同的时间片中执行,多个程序的所有指令流时间片轮转。
继续类比就发现了传输协议的问题甚至 IP 的问题。
设想一个常见的场景,在多核系统加密一条数据流,高效的方式如下(这也是 wireguard 的方式):
虽然数据流是强序的,但加密的过程是个执行过程,数据是 OBJ 呈现的样子,而执行则是对 OBJ 加工的过程,数据和执行要分离才能高效利用资源。因此没人傻到对一条数据流顺序加密。
在更底层的指令层面,几乎所有的现代处理器都支持乱序执行,道理也是如此。
但类比到 TCP/IP 分组交换网,TCP 却没有采用这种显而易见的方式。
和 “加密” 一条数据流类似,现在是 “传输” 一条数据流,只是换了谓语,TCP 却成了下面的样子:
而正确的做法应该是下面的样子:
TCP 做不到这个样子,我想还是因为它诞生太早了,在 1970 年代,人们尚未完全认识到数据和执行要分离,更别提数据和传输要分离,当时电路交换的影响还很大,物理层面接受分组交换已经是一大突破,在逻辑层面却依然还是 “电路”,它们叫 “虚电路”。TCP 握手挥手,像极了电话拨号挂断等信令。如果在 2010 年代末重新设计传输协议,事情将会大不同,比如 SRD。
早期 TCP/IP,若不是主动 ECMP,瘦网(尽力转发)几乎没有能力将数据包做多路径分发,ECMP 也只能依赖传输层元组以及更高层协议信息,在 IP 层面没有任何指导多路径分发的字段可用,但在 2010 年代大规模部署的 IPv6 协议就有 flowid 字段可用,这也算摆脱了时代的局限。
即便是 ECMP,也不敢对 TCP 进行多路径分发,因为 TCP 的核心机制积累确认太依赖强序了,多路径分发 TCP 流量会导致大量丢包误判,SACK 也救不了。
直到现在的 TCP,若想换一条等价路径,对于 IPv4,除了重连换个端口,几乎没有别的方法,因此一些 trick 就是“重连比 RTO 退避效率高多了,重连会换端口,会换 ECMP 路径,之前的老路要么断了,要么严重拥塞了,也不用等了,直接 reset 连接,靠重连换路”,或者 “用短连接 reset 将 TCP 做 UDP 用,发几个包就 reset 掉,代价就是握手,如果支持 fastopen,就完美了”。
关于 TCP 强序问题,去年写过两篇文字:TCP 和宽容,TCP CC 和宽容。
在 1970 年代 TCP/IP 肇始,IP 路由虽是逐跳转发,但最短路径路由协议也依然会收敛到同一条路径,换句话说,早期的多路径是做备份的,而不容易做负载均衡,整个 TCP/IP 协议族都天生对多路径传输不友好。
ECMP,TCP SACK 等机制只是弥补了缺陷但远非修正。
现如今的最优路由逐跳转发天然不支持多路径。在新的时代实现真正的多路径乱序传输,核心是部署一个新的路由协议或者部署 SDN 控制器对东西向流量进行干预性调度,除此之外,传输协议只能说利用了底层的多路径特征。举个例子,现如今体系结构下,就算 MPTCP 构建了 10 条 subflow,它们大概率也会经由同一条路径到达对端进而也经历同样的拥塞。
若真的学现代分时系统的方式,就应该像将数据的形式和执行的过程分离一样,将数据和传输分离,不用操心传输的过程,只关注数据交付的形式。IP 路由天生就应该将到达同一目的地的流量分发到多条路径,但就目前看来,这却是 IP 路由极力避免的。以 Dijkstra 算法为例,收敛后的视图在每个路由器看来都是一棵树,这意味着到达确定目标只有唯一一条路径,而别的路径被 “剪枝” 了,只有当最优路径不再最优时,路由才可能重新收敛到新的路径,这天然不是多路径传输的方式。
但话又说回来,分时系统本身也远非完美,Linux + SMP 一直在演化,努力克服多核场景的同步问题,大量取消对共享数据结构的访问,但根本缺陷也并非那么容易克服,情况比网络传输更严重。
在分时系统内部,执行的时间尺度与数据交付的时间尺度是同一数量级,这意味着并行处理太过分时,同步开销占比将无限增加,但凡交互,必有同步,这是免不了的,因此总有一个 “度” 的问题,将问题如何拆解更合适,这部分已经逼近极限。
但这对于网络传输并不成问题。感谢光速,让几乎任何传输都需要足够久的时间,这部分时间(us 级别)远大于数据交付的时间(ns- 级),人们早已接受了如此慢的传播速度,多路径传输的同步开销和多路径传输本身带来的收益相比微不足道。
TCP/IP 分组交换与现代操作系统同时在一个 “寒武纪大爆发” 时代开始,两者的关系非常有趣。从原理上,它们都是统计复用系统,背后都是排队论,还可以从计算机使用方式和电话使用方式不同来看,但比较着比较着就会发现问题,最初的 TCP/IP 还是带有历史的影子包袱,这些包袱一背就是 40 余年,但这就是演化本身,这是一个精彩的故事。而现代操作系统没有这样的包袱,因为计算机本身就是通用机器,若非要找一个包袱,那么还是以电话为代表,作为专用机器站在通用机器的对面。说了这么多,电话这种东西才是二者共同的前辈。
浙江温州皮鞋湿,下雨进水不会胖。