虽然TCP协议从上世纪70年代开始使用,TCP协议有着悠久,并且非常成功的历史。但是,互联网发展的深度对TCP协议的部署带来了很多的挑战。斯坦福大学的研究人员最近对2022年的研究进行了更新,提出了使用Home替代TCP的最新研究成果。TCP协议对于现代数据中心来说,它可能是不是一个很好的传输协议。研究人员从几个层面论述了TCP的几大缺陷,以及TCP协议的不可修复性,提出了Homa的几个特色。Google也曾经发表论文提出了某些过于收发数据方的新的优化建议,但是对此论文作者来说,可能也是没卵用,也是一个小的修修补补。今天笔者把其更新的主要研究成果分享如下。曾论文的完整内容,请读者从参考链接下载论文全文。
1. 摘要说明TCP的每一个重要元素,从其流导向到其对按序数据包传递的期望,都不适合数据中心。我们应该认识到,TCP的问题过于根本且相互关联,以至于无法修复;要充分利用现代网络的性能潜力,唯一的方法是在数据中心引入一种新的传输协议。Homa证明了可以创建一种避免所有TCP问题的传输协议。虽然Homa与TCP的API不兼容,但通过将其与RPC框架集成,应该可以实现其广泛应用。
2. 背景介绍TCP传输协议[9]已被证明是极其成功和适应性强的。在20世纪70年代末设计TCP时,连接到现有ARPANET的主机只有大约100台,网络链路的速度为每秒几十千比特。自那时以来的几十年间,互联网已发展到数十亿台主机,链路速度达到100 Gbit/秒或更高已是司空见惯,但TCP仍然是几乎所有应用的主力传输协议。设计出一种能够在底层技术发生如此剧变的情况下仍能存活的机制,是一项非凡的工程成就。
然而,数据中心计算为TCP带来了前所未有的挑战。数据中心环境中,数百万个核心紧密相连,单个应用程序利用数千台机器以微秒级时间尺度进行交互,这些都是TCP设计者无法预见的,TCP在这种环境下表现不佳。TCP仍然是大多数数据中心应用的首选协议,但它在许多层面引入了开销,限制了应用级性能。例如,众所周知,TCP在混合工作负载下对于短消息的尾部延迟较高[2]。TCP是“数据中心税”[3, 12]的主要贡献者,所谓“数据中心税”是指消耗数据中心中大量处理器周期的低层开销。
这篇论文的观点认为,TCP 在数据中心的挑战是无法克服的。第三节讨论了 TCP 的每一个主要设计决策,并证明它们对于数据中心来说都是错误的,带来了显著的负面影响。其中一些问题在过去已经被讨论过,但将它们集中在一起是很有启发性的。TCP 的问题影响多个层次的系统,包括网络、内核软件和应用程序。一个例子是负载均衡,它在数据中心中是处理高负载并发所必需的。负载均衡在 TCP 设计时并不存在,而 TCP 干扰了网络和软件中的负载均衡。
3. 要求在讨论 TCP 的问题之前,让我们先回顾一下任何数据中心传输协议必须解决的挑战。可靠交付。协议必须能够在网络中存在瞬时故障的情况下,将数据可靠地从一个主机传送到另一个主机。
低延迟。现代网络硬件可以实现短消息的往返时间仅为几微秒。传输协议不能显著增加这种延迟,以便应用程序体验接近硬件极限的延迟。即使在相对高的网络负载和混合流量下,传输协议也必须支持低尾部延迟。尾部延迟对于传输协议来说尤其具有挑战性;尽管如此,应该可以实现短消息的尾部延迟在最佳延迟的2-3倍以内。
高吞吐量。传输协议必须以两种不同的方式支持高吞吐量。传统上,“吞吐量”一词指的是数据吞吐量:在单个消息或流中传递大量数据。这种吞吐量仍然很重要。此外,数据中心应用需要高消息吞吐量:能够快速发送大量小消息以用于广播和洗牌等通信模式。历史上,消息吞吐量没有受到太多关注,但在数据中心中是必不可少的。
为了满足上述要求,传输协议还必须处理以下问题:
拥塞控制。为了提供低延迟,传输协议必须限制网络队列中数据包的积累。数据包排队可能会在网络边缘(连接主机到机架顶级交换机的链路)和网络核心中发生;这些拥塞形式中的每一种都带来不同的问题。
服务器核心的高效负载均衡。十多年来,网络速度一直在快速增长,而处理器时钟速度几乎保持不变。因此,单一核心已无法跟上单一网络链路的速度;进出负载都必须分布在多个核心上。这在多个层面上都是如此。在应用层面,高吞吐量服务必须运行在多个核心上,并将其任务分配给这些核心。在传输层,单一核心无法跟上高速链路,尤其是对于短消息。负载均衡对传输协议有两方面的影响。首先,它可能引入开销(例如,使用多个核心会导致额外的缓存未命中以保持一致性)。其次,负载均衡可能导致热点,即负载在核心间分配不均;这是软件层面上的一种拥塞。负载均衡开销现在是尾延迟的主要来源之一,并且受到传输协议设计的影响。
NIC负载。有越来越多的证据表明,基于软件的传输协议不再合理;它们无法以可接受的成本提供高性能。例如:
• 最好的软件协议实现的端到端延迟要比通过内核旁路直接与NIC通信的实现高出3倍以上。
• 软件实现的消息吞吐量比起基于NIC卸载的实现要低5-10倍。
• 在驱动100 Gbps网络达到80%双向利用率时,仅在网络堆栈中就消耗了10-20个核心。这不是一种资源有效的使用方式。因此,未来的传输协议需要转向专用的NIC硬件。传输协议不能有不允许硬件实现的特性。需要注意的是,基于NIC的运输不能消除软件负载均衡问题:即使传输在硬件中,应用软件仍将分布在多个核心上。
关于 TCP 的所有要素都是错误的,本节讨论了 TCP 的五个关键特性,几乎涵盖其所有设计:
流媒体数据导向连接导向带宽共享发送方驱动的拥塞控制顺序数据包传递这些特性中的每一个都代表了数据中心传输的错误决策,并且每个决策都带来了严重的负面后果。
3.1 流媒体数据导向
TCP 的数据模型是字节流。然而,这对于大多数数据中心应用程序来说不是合适的数据模型。数据中心应用程序通常交换离散消息以实现远程过程调用。当消息在 TCP 流中序列化时,TCP 对消息边界一无所知。这意味着当应用程序从流中读取时,无法保证它将接收到完整的消息;它可能接收到少于完整消息的内容,或者是多个消息的一部分。基于 TCP 的应用程序必须在序列化消息时标记消息边界(例如,通过在每个消息前加上其长度),并且它们必须使用此信息在接收时重新组装消息。这会引入额外的复杂性和开销,例如维护部分接收消息的状态。
对于软件负载平衡来说,流模型是灾难性的。考虑一个使用线程集合来处理从多个流到达的请求的应用程序。理想情况下,所有线程都将等待任何一个流上的传入消息,并将消息分配到线程中。然而,使用字节流模型无法保证读取操作返回整个消息。如果多个线程都从一个流中读取,可能会出现单个消息的部分被不同线程接收到的情况。原则上,线程之间可能协调并在其中一个线程中重新组合完整的消息,但这在实际上过于昂贵。
3.2 连接导向
TCP要求为每个与应用程序通信的对等方保持长期的连接状态。在数据中心环境中,连接是不可取的,因为应用程序可能有数百或数千个连接,导致空间和/或时间上的高开销。例如,Linux内核为每个TCP套接字保持大约2000字节的状态,不包括数据包缓冲区;在应用程序级别还需要额外的状态。
Facebook发现为每个应用程序线程和每个服务器之间建立单独连接的内存需求“代价过高”[20]。为了减少这些开销,应用程序线程通过一组代理线程进行通信,这些代理线程管理与所有服务器的连接。这允许每个服务器的单个连接在该主机上的所有应用程序线程之间共享,但这增加了通过代理进行通信的开销。为了减少代理开销,Facebook在可以容忍UDP不可靠性的请求中使用UDP而不是TCP,但这牺牲了拥塞控制。
由于NIC芯片资源有限,当将传输卸载到NIC时,连接状态的开销也成为问题。在Infiniband社区中,这个问题是众所周知的[5, 10, 11]。多年来,RDMA NIC只能缓存几百个连接的状态;如果活动连接的数量超过缓存大小,则信息必须在主机内存和NIC之间交换,导致性能显著下降。
连接的另一个问题是,在传输任何数据之前,它们需要一个设置阶段。在TCP中,设置阶段具有非平凡的成本,因为它需要主机之间额外的往返。传统上,连接是长期存在的,因此设置成本可以分摊到大量请求中。然而,在新的无服务器环境中,应用程序的生命周期非常短,因此更难以分摊连接设置的成本。
3.3 带宽共享
在 TCP 中,当主机的链路过载(无论是传入还是传出流量)时,TCP 尝试在活动连接之间平均共享可用带宽。这种方法也被称为“公平调度”。 不幸的是,这样的调度机制在负载下表现不佳。当接收多个大消息时,带宽共享会导致所有消息完成得很慢。像 SRPT(最短剩余处理时间)这样的运行到完成的方法提供了更好的整体响应时间,因为它们将所有可用资源一次性专用于单个任务,确保其快速完成。
由于 TCP 没有关于消息边界的信息,因此很难在 TCP 中实现运行到完成;因此,它不知道何时一个任务“完成”。 此外,尽管名为“公平调度”,但 TCP 的方法对短消息非常不利。图 1 显示了在负载严重的网络上运行时,不同大小消息的往返延迟如何变慢,与在未加载网络上的相同大小消息相比。使用 TCP 时,短消息的减速几乎比最长消息差 10 倍。DCTCP 在一定程度上缩小了差距,但短消息仍然比长消息受到 3 倍的更差对待。在数据中心环境中,短消息的延迟至关重要,因此这种歧视是个问题。
3.4 发送方驱动的拥塞控制
TCP 的拥塞控制由发送方驱动,当检测到拥塞时,发送方会自愿降低其数据包传输速率。发送方对拥塞没有直接的了解,拥塞可能发生在核心网络中或机架顶部交换机与接收方之间的边缘链路上,因此它们依赖于与缓冲区占用相关的拥塞信号。在最坏的情况下,交换机队列溢出,数据包被丢弃,导致超时。更常见的是,当队列长度达到某个阈值时,交换机会生成 ECN 通知 [25],或者发送方检测到由于排队导致的往返时间增加 [18, 13];一些较新的方法使用可编程交换机生成更精确的信息,例如确切的队列长度 [14, 1]。然后,发送方使用这些信息来减少数据包传输。
TCP 中的拥塞控制受到两个限制的阻碍。首先,只有在缓冲区占用时才能检测到拥塞;这几乎保证了在网络负载时会出现一些数据包排队。其次,TCP 没有利用现代网络交换机中的优先级队列。因此,所有数据包都被平等对待,由长消息(吞吐量比延迟更重要)产生的队列将导致短消息的延迟。
这些限制导致了一个“选择你的毒药”的两难困境,在这种情况下,很难同时优化延迟和吞吐量。确保短消息的低延迟的唯一方法是在网络中保持队列长度接近于零。然而,这样做会有缓冲区不足的风险,即使有可能利用这些链路的流量,它们也会保持空闲状态;这会降低长消息的吞吐量。在面对流量波动时,唯一能保持链路充分利用的方法是让缓冲区在稳态下积累,但这会导致短消息的延迟。
此外,发送者大约需要一个往返时间(RTT)才能发现流量变化,因此发送者必须根据过时的信息做出决策。随着消息变短和网络变快,越来越多的消息将在少于一个RTT的时间内完成,这使得发送者收到的信息变得越来越不可靠。
对TCP和其他流式传输方法(如RDMA)的拥塞控制进行了广泛研究。这些努力带来了相当大的改善,但在不打破TCP的一些基本假设的情况下,延迟与吞吐量的两难困境不太可能彻底解决。
3.5 顺序数据包传递
TCP假设数据包会按照发送方传输的相同顺序到达接收者,并假设无序到达意味着数据包丢失。这极大地限制了负载均衡,导致硬件和软件中的热点,并因此导致高尾延迟。
在数据中心网络中,执行负载均衡的最有效方法是执行数据包喷洒,即每个数据包都独立通过交换结构路由以平衡链路上的负载。然而,数据包喷洒不能与TCP一起使用,因为这可能会改变数据包到达目的地的顺序。相反,TCP网络必须使用流一致路由,即给定连接的所有数据包都通过网络结构的相同路径。流一致路由确保顺序数据包交付,但实际上保证了即使整个网络负载较低,网络核心中也会有负载过重的链路。引起拥塞所需的一切就是两个大的流量哈希到同一个中间链路;这个热点将在流的整个生命周期中存在,并导致其他通过受影响链路的消息延迟。
我假设流一致路由是数据中心网络核心几乎所有拥塞的原因。
按照顺序的包传递在软件中也会导致热点。例如,Linux通过在多个核心之间分配处理传入数据包来在软件中执行负载均衡;这是维持高数据包速率所必需的。每个传入的数据包在到达应用程序之前由内核在两个不同的核心上处理(可能在第三个核心上)。为了确保按顺序的数据包传递,给定TCP连接的所有数据包必须通过相同的核心序列。当两个或多个活动连接散列到相同核心时,这导致核心负载不均;再次,只要连接是活跃的,热点就会持续。文献[21]中的测量表明,热点是软件引起的TCP尾延迟的主要原因。修正(2023年1月):本小节的第一段不正确。数据包乱序到达不一定会触发TCP中的数据包重传。诸如三重重复ACK和RACK之类的机制允许TCP在不重传的情况下容忍一定程度的数据包乱序。然而,专家告诉我,数据中心网络中的不对称性可能会导致超过TCP容忍度的显著数据包乱序。此外,NIC和Linux网络栈中的性能优化(如LRO和GRO)在遇到即使是适度的乱序时也会失效,导致显著的性能下降。因此,网络硬件和Linux内核软件都试图保持数据包排序,导致上述问题。
4. TCP 无法修复对 TCP 问题的一种可能响应是采用逐步的方法,在保持应用程序兼容性的同时逐步解决问题。目前已经有许多类似的尝试,并且取得了一些进展。
然而,这种方法不太可能成功:问题太多,而且这些问题已经深深嵌入在 TCP 的设计中。
以拥塞控制为例。近年来,TCP 的这一方面可能比其他方面研究得更多,并且已经设计出许多新颖而巧妙的技术。最早的技术之一是 DCTCP [2];它在尾部延迟方面提供了显著改善(见图 1),并已被广泛实施。最近的建议如 HPCC [14] 提供了令人印象深刻的额外改进(它们未包含在图 1 中,因为它们没有 Linux 内核实现)。然而,所有这些方案都受到 TCP 的基本方面的限制,例如基于缓冲器占用的弱拥塞信号、无法使用交换机优先队列以及其顺序交付要求。
只有通过打破 TCP 的一些基本假设,才能实现显著的额外改进。图 1 中的 Homa 曲线表明可以实现相当大的改进(尽管未显示在图 1 中,Homa 也比 HPCC 等新提案提供了更好的尾部延迟)。
增量方法的一个问题是,TCP有许多相互关联的问题。例如,缺乏消息边界使得实现SRPT变得困难,并限制了用于拥塞控制的信息量。因此,TCP的许多不同部分必须进行更改,才能看到改进。此外,TCP 的问题不仅涉及其实现,还涉及其 API。为了在数据中心中最大化性能,TCP 必须从基于流和连接的模型切换到基于消息的模型。这是一个将影响应用程序的根本性改变。一旦应用程序受到影响,我们不妨同时解决所有其他 TCP 问题。关键是 TCP 没有任何部分值得保留。我们需要一种在每个重要方面都与 TCP 不同的替代协议。幸运的是,这样的协议已经存在:Homa。Homa 提供了一个存在性证明,证明 TCP 的所有问题实际上都是可以解决的。
5 HomaHoma 代表了一种数据中心网络传输的新设计。其设计基于对 TCP 问题的了解,以及使用 Infiniband [23] 和 RDMA 实现大规模数据中心应用的经验。Homa 的设计在第 3 节所讨论的每一个方面都与 TCP 不同。本节简要总结了 Homa 的特点;详细信息,请参阅 [19] 和 [21]。
5.1 消息
Homa 是基于消息的。更准确地说,它实现了远程过程调用(RPC),其中客户端向服务器发送请求消息,并最终收到响应消息。消息的主要优点在于它们向传输层公开了可调度单元。这使得负载均衡更加高效:多个线程可以安全地从单个套接字读取,协议的基于 NIC 的实现可以通过内核绕过直接将消息派发给一组工作线程。明确的消息边界还使得在传输中实现跑至完成的调度成为可能,例如 SRPT,并提供了更强大的拥塞信号(见下文)。
消息相对于流有一个缺点:很难对单个大消息的实现进行流水线处理。比如,在整个消息接收完之前,应用程序无法接收消息的任何部分。因此,单个大消息的延迟会比通过流发送的相同数据更高。然而,可以通过并行发送多个消息来处理大数据传输,这允许在消息之间进行流水线处理。
5.2 无连接
Homa 是无连接的。没有连接建立的开销,应用程序可以使用单个套接字来管理与任意数量的对等方的任意数量的并发 RPC。每个 RPC 独立处理:并发 RPC 之间没有顺序保证。
Homa 维护的状态分为三大类:
– 套接字:Homa 每个套接字的状态大致相当于 TCP,但 Homa 应用程序可以只用一个套接字,而 TCP 应用程序需要每个对等方一个套接字。
– RPC:Homa 为每个活动的 RPC 保留大约 300 字节的状态。一旦 RPC 完成,这些状态就会被丢弃,因此状态总量与活动 RPC 的数量成正比,而不是与对等方的总数成正比。
• 远端:每个 Homa 主机为每个其他主机保留大约 200 字节的状态,其中大部分是 IP 级路由信息。这比 TCP 为每个连接维护的 2000 字节状态要小得多。尽管没有连接,Homa 确保了 RPC 的端到端可靠性(或在无法恢复的网络或主机故障后报告错误)。应用程序无需维护额外的超时。流量控制、重试和拥塞控制等机制是通过每个 RPC 状态实现的;可以这样理解 Homa:它为每个 RPC 实现了一个短暂且轻量级的连接。
5.4 接收方驱动的拥塞控制
Homa 从接收方而非发送方管理拥塞。这样做是合理的,因为拥塞的主要位置是接收方的下行链路(Homa 消除了核心拥塞,如下文第 5.5 节所述)。接收方了解其所有传入消息,因此更有能力管理这种拥塞。当发送方传输消息时,它可以单方面发送一些未安排的包(足以覆盖往返时间),但剩余的计划包只能在接收到接收方的许可后发送。通过这种机制,接收方可以限制其下行链路的拥塞,并且还可以使用许可来优先处理较短的消息。
消息提供了一个强大的拥塞信号,这是基于流的协议所不具备的。尽管消息到达是不可预测的,但一旦看到消息的第一个数据包,就可以知道消息的总长度。这使得可以采取主动的拥塞控制方法,例如在此消息的生命周期内限制其他消息,并在此消息完成时再次增加它们。相比之下,TCP只能基于缓冲区占用进行被动反应。如果许多发送者同时发送未排定的包,可能会发生Incast,但Homa的RPC导向使得简单的缓解措施成为可能;详情请参阅Homa的论文。
5.5 乱序数据包
Homa的一个关键设计特性是它可以容忍乱序到达的数据包。这为负载均衡提供了相当大的灵活性。例如,可以使用数据包级喷洒来分配数据包,而不是像TCP那样流一致的路由。如果Homa得到广泛部署,我推测只要核心网络没有系统性过载,核心拥塞将不再是一个显著的网络问题。Homa对乱序到达的容忍度也为软件中的负载均衡提供了更多的灵活性。
结论TCP 是数据中心计算的错误协议。TCP 设计的每个方面都是错误的:没有值得保留的部分。如果我们想消除“数据中心税”,我们必须找到一种方法将大部分数据中心流量转移到一种截然不同的协议。Homa 提供了一种似乎可以解决 TCP 所有问题的替代方案。将 Homa 广泛使用的最佳方式是将其与大规模数据中心应用程序的底层 RPC 框架集成。
参考资料
https://news.ycombinator.com/item?id=42168997
https://systemsapproach.substack.com/p/its-tcp-vs-rpc-all-over-again
https://arxiv.org/pdf/2210.00714
https://www.micahlerner.com/2021/08/29/a-linux-kernel-implementation-of-the-homa-transport-protocol.html
作者:james.zhu来源:SIP实验室原文:https://mp.weixin.qq.com/s/fe0CdLLyRzEzXAjpT03HpQ