随着公有云中分离式存储(disaggregated storage)的广泛部署,网络在构建高性能与高可靠性的云存储服务中扮演着核心角色。在Azure平台,我们选择了远程直接内存访问(RDMA)作为数据传输方式,旨在将其应用于存储的前端(计算虚拟机与存储集群间)及后端(存储集群内部)流量,以充分发挥其优势。鉴于计算和存储集群可能分散在Azure区域内的不同数据中心,我们需要在区域范围支持RDMA技术。
本文介绍了我们在Azure中部署区域范围内(intra-region)RDMA以支持存储工作负载的经验。面对基础设施的高度复杂性和异构性所带来的新挑战,如不同RDMA网卡(NIC)间的互操作性问题,我们对网络基础设施进行了多项优化调整。目前,Azure中约70%的流量已通过RDMA传输,且区域内RDMA已在所有Azure公共区域得到全面支持。RDMA技术的引入,显著提升了硬盘I/O性能并减少了CPU核心占用。
-----
今天,我想分享的是一个历时八年的长期项目,关于我们如何在Azure中成功部署RDMA技术。

本次演讲将涵盖以下几个要点:我们采用RDMA技术替代TCP协议,在Azure中实现了分离式存储。这一转变旨在减少CPU资源的消耗,并优化I/O操作的延迟和稳定性。使这一切成为可能的关键在于基于通用以太网的RDMA技术(RoCEv2)。这一技术的实现背后,是我们团队的多项创新成果,包括我们论文中提及的一些内容,如经过细致优化的存储库、调试工具(RDMA Estats),以及DCQCN、PFC等先进的拥塞控制协议,还有众多其他技术上的改进与突破。
我们在Azure中实施的变革规模庞大。目前,Azure网络中约有70%的流量(以字节和数据包计)已经采用了RDMA技术,相比之下,TCP的使用则远远不及。

我将遵循七个核心问题的框架来展开今天的分享:首先,明确问题所在;接着,阐述这个问题为何重要;然后,介绍我们是如何解决这个问题的;此外,还会探讨之前的方法为何不足,以及我们在实施过程中遇到的挑战和应对策略;最后,总结一些普遍的教训和尚未解决的研究问题。

问题是什么?Azure在处理存储流量时占用了过多核心资源。这具体意味着什么?
在公有云环境中购买虚拟机时,内存和CPU是作为一个整体单元提供的,我们通常称之为计算服务器。而所有的虚拟硬盘(或称为存储卷)则挂载在远程的存储服务器上。因此,当虚拟机执行任何存储操作或I/O操作时,这些操作实际上会转化为网络流量,因为数据需要在计算服务器与远程存储服务器之间传输。
例如,如果虚拟机执行了一个硬盘写入操作,这个操作的数据会通过网络前端发送到Azure的存储系统或存储服务器上。在那里,数据可能会被复制三次,这会产生额外的后端网络流量。因此,存储I/O操作在本质上就是网络流量的一个组成部分。这种设计虽然有其优势,但也可能导致在处理大量存储I/O时,计算服务器的核心资源被过度消耗。

我们过去常常依赖TCP协议来实现数据传输,但众所周知,TCP协议在处理过程中会消耗较多的CPU资源。这一协议栈既在发送端也在接收端运行,它要求通用CPU来处理数据包的封装工作,同时还涉及到复杂的拥塞控制协议等。更为关键的是,TCP协议栈在内核空间运行,这意味着它可能会受到中断的影响,从而引发一系列问题。随着通用CPU利用率的提升,存储I/O事务将不可避免地面临延迟增加的问题。

为何重要?在Azure及众多公有云中,由于采用了分离式存储架构,网络中的大部分流量都与存储活动紧密相关。特别是在Azure中,这一比例高达近70%。因此,对存储流量进行优化,对于提升整体性能和降低成本而言,具有极其重要的意义。

如果我们能够减少存储流量对CPU资源的消耗,这将对Azure产生直接的经济效益。从商业模式来看,公有云服务商通常会批量采购Intel、AMD等厂商的CPU,并按时段出租给客户。减少CPU在存储流量上的消耗,就意味着成本节约,这直接关乎到我们的盈利能力。同时,客户也能享受到更高效的存储I/O性能,从而提升其业务体验。因此,这一优化对于我们作为服务提供商以及我们的客户而言,都是双赢的局面。

解决方案是什么?当发现通用CPU频繁地执行重复性任务时,一个标准的计算机科学解决方案便是将这些任务卸载到专用硬件上,以期获得性能上的飞跃。这正是我们引入RDMA技术的初衷。
对于RDMA的新手而言,通过TCP与RDMA的对比图,可以大致了解RDMA的工作原理:一个简洁的RDMA发送操作。发送方创建一个缓冲区,填充数据后,将此缓冲区注册到网卡(NIC)上。接收方也创建并注册相应的缓冲区。随后,两块NIC交换IP地址及虚拟内存地址,数据即可由接收方拉取或由发送方推送,整个过程中通用CPU无需介入。这种设计带来的优势是显而易见的。

这是一张八年前的幻灯片,那是我们用来向管理层阐述项目价值的工具。回想2015年,我们使用的是40Gbps的网卡。虽然技术已有所发展,但即便在当时,对于小到中等大小的数据包,单个RDMA线程就能轻松达到网络带宽的上限,而TCP则因CPU瓶颈而无法做到。此外,RDMA的延迟也远低于TCP。如今,随着网络速度提升至100Gbps甚至更高,RDMA的优势更加显著。

RDMA并非我们的发明,它是一项源自上世纪90年代末的老技术,最初由InfiniBand实现,专为高性能计算(HPC)设计。早期应用于大型集群(NOWs和COWs),这些集群规模虽大,但与今天的云环境相比仍显“小巧”。InfiniBand从OSI模型的最底层到最顶层都采用了独特的网络技术,与以太网IP不兼容,且成本高昂,因此难以在云规模下部署。
鉴于Azure及所有公有云均基于以太网IP构建,我们必须在保持这一基础架构的同时实现RDMA。这便是RoCE技术的用武之地。
下面我将详细解释我们的实现方法。

实现这一过程并非易事,其挑战可以用这张图片最好地概括:TCP/IP以太网如同家用车,无需特殊培训即可驾驶,虽能容忍路况不佳,但速度有限;而RDMA则如同F1赛车,对路况要求极高,驾驶员需经特殊培训,持续调整并监控性能。

为了克服网络丢包问题,我们采用了RoCEv2技术,它支持优先级流控制(PFC)、缓冲管理及拥塞控制等功能。至于“驾驶员培训”,则意味着不能直接套用TCP代码,而需编写专门的RDMA代码。此外,我们还开发了RDMA Estats等工具来监控性能。
要实现RoCEv2的广泛部署,我们已发表了相关研究成果,现在我将简要回顾一下。

我们的目标是在以太网IP网络上模拟InfiniBand的RDMA性能。那么,具体如何实现呢?基本上,我们需要采用InfiniBand的第四层协议(即替代TCP的协议),并将这些数据封装在UDP数据包中。这些数据包在网络上传输时,无需对路由器做任何改动,因为它们仅仅是UDP数据包。我们的期望是,除了特定的一点外,网络几乎无需任何变动。而底层的InfiniBand协议,网卡能够自动识别并处理,让网卡感觉就像在使用InfiniBand通信一样,同时路由器和交换机则继续传输标准的以太网IP数据包。
然而,这里存在一个挑战:InfiniBand的第四层协议对丢包非常敏感,它需要一个几乎无损的网络环境,这通常被称为“无损网络”。但在我看来,“无损”这个词并不准确,因为世界上没有绝对无损的网络,总会有CRC错误等问题发生,但我们需要尽量减少这些错误。这样做的目的是为了实现快速启动和高可靠的传输,这对我们撰写第一篇论文时来说至关重要。它显著降低了尾延迟,允许ACK的合并,并带来了其他诸多优势。


以太网和IP网络都不是无损网络;当队列达到饱和时,数据包有可能被丢弃。但幸运的是,有一种技术叫做PFC(优先级流控制),它能有效减少这些网络中的丢包现象。其运作机制,简而言之,就是当缓冲区即将满溢时,会向上游发送器发出停止传输的指令。这样一来,拥塞的交换机通过告知上游路由器暂停发送,成功避免了数据包的丢失,原本可能丢失的数据包因此得以保留。
网络内部设有8种优先级,这意味着在优先级流控制下,即便某些优先级(如绿色数据包)的传输被暂停,其他优先级的传输仍可继续进行。确保网络得到“正确配置”是关键,它要求合理设置缓冲区大小,以防止因拥塞而导致的丢包。然而,这样的配置也带来了新的挑战。PFC帧的发送和接收在网络中创建了状态感知,这可能会带来一系列新的问题。

值得注意的是,PFC是基于端口而非流的。比如,若一个路由器在端口四上处理三个数据流,而该端口启用了PFC,那么一旦队列开始积压,端口四将暂停所有通过该端口的流量,包括那些本应从其他端口(如端口一、端口二)传输的流量。这种设计意味着,如果端口一连接的路由器正在发送流量1和3,而端口四的暂停将影响到端口一上的所有流量,包括与拥塞无直接关系的流量3。这种情况可能导致所谓的“队头阻塞”(head-of-line blocking)或“受害者流”(victim flow)问题,在小型网络中尚可通过全面管理应用程序来控制,但在大型数据中心中,若PFC的反馈效应级联发生,则可能引发严重的网络问题。


为了应对这些挑战,我们将PFC作为最后的手段,并尽可能减少其使用。在大多数情况下,我们依赖端到端的拥塞控制协议,特别是基于显式拥塞通知(ECN)的RTT无感知DCQCN协议。选择基于ECN的协议是因为它避免了数据包丢失,仅通过ECN标记来传递拥塞信号,且ECN功能在现有硬件中广泛可用。
拥塞控制协议被特意设计成不依赖于RTT的特性。这背后的考量在于我们的应用场景:涉及虚拟机与存储服务器的协作。如果系统仅限于在微秒级的RTT内有效工作,那意味着服务器、计算资源和存储设备必须紧密部署于同一数据中心内,这无疑限制了布局的灵活性。可能面临电力不足或空间限制的困境。因此,需要赋予数据中心设计者足够的灵活性,以便根据实际需求将存储设施部署在稍远的位置。
当存储设施被置于不同数据中心时,RTT可能会跃升至毫秒级,而微秒与毫秒之间的差异是显著的。这就需要一种能够跨越这两个截然不同时间尺度运行的拥塞控制协议。或许有人会问:“既然在设计之初就能预知RTT,为何不直接采用适应某一特定RTT的协议?”但问题在于,虚拟机需要为客户提供连接任何硬盘的灵活性,不能简单地根据数据中心位置来限定RTT级别。因此,同一种拥塞控制协议必须能够无缝适应从微秒到毫秒级别的RTT变化。

至于如何驱动这一系统,它并非简单地复用TCP套接字代码即可实现。为此,我们投入了大量编码工作,建立了一系列存储库,这些库为开发者提供了一层抽象层。开发者可以继续主要编写套接字代码,而在底层,这些代码会被自动转换为RDMA操作,如发送、接收、读取和写入,具体取决于内存的注册方式。选择最优的RDMA模式需综合考虑多种因素,其中传输大小尤为关键。所有这些转换和选择过程对开发者而言都是完全透明的。
在探讨网络稳定性时,设想您管理着一个庞大的网络体系,线缆故障时有发生,这不可避免地会导致数据包的损坏。TCP对此具有一定的容错能力,只要数据包损坏率保持在十万分之一或更低,它就能正常运作。然而,RDMA则对损坏率更为敏感,它要求损坏率低于百万分之一。面对网络中的这类脆弱环节,我们部署了自动化系统,能够自动侦测问题链路并迅速采取移除或绕行措施,但这一过程需要时间,可能长达几分钟。在此期间,为了维持系统性能,我们设计了自动回退机制,将数据传输临时切换回TCP,待问题解决后再恢复RDMA。所有这些操作都是无缝衔接、对最终用户完全透明的。

再谈谈性能监控方面,我们特别开发了RDMA Estats,它与TCP Estats类似,但专为RDMA设计。这项工具能够深入每个RDMA操作,提供详尽的延迟分析报告。这张图中,可以清晰看到RDMA发送操作的各个阶段,其中两个关键的时间间隔尤为重要:一是客户端端到端的总延迟(T6-T1),它反映了从发送到接收的完整过程;二是硬件延迟(T5-T1),这直接关联到网络硬件的性能表现。不过,获取这两个时间戳并非易事,因为它们分别来源于网卡和CPU,而这两者虽共处一机,却各自独立计时。为确保数据准确性,我们不得不投入大量精力来同步时钟,并避免设备过载。这些早期投资为我们后续的调试工作奠定了坚实基础,帮助我们解决了诸如网卡在多流间共享拥塞状态等复杂问题。

回顾项目历程,我们最深刻的教训在于:尽管我们曾以为需要开发全新的拥塞控制算法,但最终发现,系统整体的兼容性和适应性才是成功的关键。从项目启动之初,我们就致力于与现有硬件和异构环境无缝对接,而非追求纯粹的从零开始的设计。通过反复的测试、监控、服务优化和向后兼容性验证,我们不断修正方向,尽管过程中也犯过不少错误,但这些都成为了我们宝贵的经验积累。
我们深知,任何声称“无需调整”的系统都是不切实际的幻想。在长达八年的运行过程中,流量模式的任何微小变化都可能对系统产生深远影响。就连来自同一供应商的网卡,在处理拥塞反馈包时也可能存在细微差异,这些问题都需要我们投入大量时间和精力去逐一解决。

最后,我想强调的是,构建高性能系统必须遵循联合设计的原则。虽然分层结构有其优势,但只有当系统中的每个组件都能紧密协作时,才能真正发挥出最佳性能。目前,我们仍面临一些未解难题,如无PFC的RDMA应用、路由器缓冲管理的优化以及RDMA在虚拟机中的集成等。

值得一提的是,我们已经在Azure上成功实现了从TCP到RDMA的迁移,每天处理的数据量高达EB级(即10^19字节),其中70%的流量由RDMA承载。而TCP则排名第二。我们的RDMA网络不仅能在100Gbps乃至更高速度下稳定运行,还能支持长达100公里的链路连接。这无疑是全球范围内最大规模的RDMA部署之一。
Source:NSDI'23 - Empowering Azure Storage with RDMA, https://www.youtube.com/watch?v=kDJHA7TNtDk
--【本文完】---
近期受欢迎的文章:
更多交流,可添加本人微信
(请附姓名/单位/关注领域)





