目录
Abstract
1.Introduction
2. Design Choices and Observations
2.1 Design Choices for RDMA-Based RPC
2.2 In-Bound vs. Out-Bound Asymmetry
2.3 Bypass Access Amplification
3. RFP: Remote Fetching Paradigm
3.1 Design Overview
3.2 Challenges and Solutions
4. Evaluation
4.1 An RFP-Based Application
5. Related Work
6. Conclusion
远程直接内存访问(RDMA)已广泛部署在现代数据中心中。 然而,RDMA的现有用法导致性能和重新设计成本之间的两难抉择问题。 它们或者直接用RDMA对应的操作原语(服务器回复)替换相应的基于Socket套接字的发送/接收原语,这只能实现适度的性能提升; 或者通过使用单面RDMA操作来完全绕过服务器(服务器旁路),从而进一步提高性能,但代价是重新设计软件。
在本文中,我们介绍了两个关于RDMA的有趣观察。 首先,RDMA具有不对称的性能特征,可用于提高服务器回复的性能。 其次,在许多情况下,跨过服务器进行通信不如预期的那么好,因为如果服务器被完全绕过,则可能需要更多轮的RDMA。 因此,我们引入了一种称为远程抓取范式(RFP)的新RDMA范例。 尽管RFP要求用户设置多个参数以实现最佳性能,但它支持传统的RPC接口,因此无需重新设计特定于应用程序的数据结构。 此外,通过适当的参数,它可以实现比以前的范例更高的IOPS。
我们基于RFP设计并实现了一个内存中的Key-Vaule Store,以评估其有效性。 实验结果表明,与server-reply和server-bypass相比,RFP将性能提高了1.6×~4倍。
RDMA是一种新颖的网络技术,提供低延迟,高带宽和绕过服务器内核的特性,已广泛部署在现代数据中心[4,8,10,15,19,23,29,30,34]。 RDMA的一个常见用法是用相应的RDMA相应的原语替换原始TCP / IP套接字发送/接收原语,以便可以实现相同的RPC接口[7,9,10,19,31,33,34]。 这种方式可以最小的编程成本提高应用程序的性能。 例如,RDMA-Memcached [10]已将此方法应用于Memcached [21],并获得了它与使用TCP / IP相比,性能提高了4×〜6倍。我们将这种设计范式表示为server-reply模式,因为它要求服务器将结果回复给客户端。
但是,上述方法并没有真正释放出RDMA的所有功能。 RDMA的标志性功能是它还提供单向操作,完全绕过远程机器上的CPU和OS内核。 因此,使用RDMA的另一方面是让客户直接访问服务器的内存。 最近的作品如Pilaf [23]和FaRM [4]在这方面做了很多工作,并验证了绕过服务器内核可以比基于服务器回复的应用程序快100%[4,23,30, 32]。我们将这种设计范式表示为server-bypass 模式[23]。
虽然减轻服务器CPU处理网络数据包可以获得更好的性能,但它依赖于开发人员设计特定的数据结构和算法,因此单边RDMA操作对于给定问题是可行的。 例如,Pilaf [23](一个Key-Value Store)使用CRC64在客户端通过发送GET请求进行数据竞争检测(using server-by pass)和通过发送PUT请求(using server-reply),同时它还设计了一个特定的哈希表减少完成GET请求的RDMA操作数。 这就是重新设计成本和性能之间的两难选择。 更重要的是,这些特殊的数据结构通常是特定于应用程序的。 例如,设计用于在键值存储上提供GET / PUT操作的数据结构不能用于其他类型的应用程序,例如那些具有简单统计操作的应用程序[30]。
为了解决这个难题,我们提出了一种新的基于RDMA的RPC范例,叫做Remote Fetching Paradigm(RFP)。 在RFP中,服务器处理从客户端发送的请求,因此其CPU利用率与传统RPC接口类似。 因此,使用传统RPC的应用程序可以保持基本不变。 同时,RFP实现了比server-reply和server-bypass更高的性能,这来自图1中所示的两个观察结果。
第一个是In-bound与Out-bound请求不对称。具体地,发出单侧RDMA操作(即,Out-Bound RDMA)具有比服务一个(即,In-Bound RDMA)高得多的开销。这是因为,以RDMA Read为例,发布方需要维护某些上下文,既涉及软件也涉及硬件,以确保操作发送和完成,而服务端完全由硬件处理。因此,以InfiniBand的FDDM网络接口卡(RNIC)为例,In-bound RDMA(约11.26 MOPS1)的峰值IOPS(每秒输入/输出操作)约为5倍。出境RDMA(约2.11 MOPS)。这解释了为什么Server-Reply模式是次优的:除了不绕过服务器的CPU之外,它还要求服务器发出RDMA操作,这受到Out-bound RDMA限制的限制。后者很快就会饱和,而In-bound IOPS远未被客户端请求所饱和。在上面的示例中,客户端只发出一个RDMA READ操作,并由服务器处理。它在发布方被称为Out-Bound RDMA,并在另一方被称为In-Bound RDMA。
第二个观察是RDMA跨内核访问请求数量扩大,这导致在Server-bypass预期性能与的测量性能之间存在显着差距。 前者对应于理想情况,其中仅需要一个RDMA操作来完成请求,这在现实中通常是行不通的。 根本原因是绕过了服务器上的CPU处理,并且在更多RDMA操作轮次的情况下,多个客户端需要协调它们的访问以避免数据访问冲突! 此外,他们可能还需要额外的RDMA操作来进行元数据探测,以找到数据存储在服务器上的位置。 因此,Server-bypass的测量性能通常远低于其预期的性能。 例如,即使对于读取密集型工作负载,Pilaf对每个GET请求平均使用3.2 RDMA操作。 当冲突很严重时(例如,写入密集型工作负载),性能会更差。
实施这一新RFP范式有两个主要挑战。 第一种是客户端应该从服务器获取结果.Astraw-man设计是客户端在服务器上重复轮询可能的结果,这确保了低延迟,但是以浪费的远程RDMA读取和客户端的高CPU消耗为代价, 以及在服务器端浪费的In-bound RDMA操作。 第二个挑战是从服务器获取结果的大小,因为客户端不知道RPC调用的响应大小。 使用RDMA操作分别获取大小需要为每个RPC调用至少进行两次远程提取,从而不必要地降低性能[4,23]。
为了应对这些挑战,RFP使用混合机制,在重复远程提取和服务器回复之间自适应地切换.A client使用RFP将在发送请求后首先连续尝试从服务器获取结果。 但是如果在重试的某个阈值之后它无法获取结果,它将切换到传统的Server-Reply模式并等待服务器将结果发回。 应根据硬件配置确定阈值,以便在性能和客户端CPU消耗之间实现良好的折衷。 我们的机制根据服务器负载自动切换连续远程提取和服务器回复。 因此,当服务器负载变得极高时,RFP至少与服务器-回复范例具有相同的性能。
此外,我们设计了一种inline-based的机制,要求客户端一次获取数据区域和大小。 通过选择适当的提取大小,我们能够通过单个RDMA操作最大化获得整个结果的机会。 此机制可以显着减少用于RPC调用的平均RDMA操作数,尤其是当结果的大小通常较小时。 在RFP中,根据应用特性和RNIC配置自适应地设置提取大小,以便能够为具有不同结果大小的应用保证最佳性能。
为了计算最佳RDMA读取重试次数和获取大小,我们将问题建模为参数选择问题。 我们的解决方案利用硬件特性来获取这些参数的下限和上限,并通过预运行和在线采样将它们连接到应用程序特征,以获得最佳性能结果。 由于使用不适当的参数可能会抵消使用RFP的性能优势,因此用户应仔细选择这些参数,这在以前的工作中是不需要的。 但是,正如我们将在3.2节中讨论的那样,有用参数的范围非常有限,因此这个选择过程的开销是可以接受的。
本文的主要贡献如下:(1)我们报告了关于RDMA及其使用范式的两个关键观察结果; (2)我们提出了一种新的基于RDMA的RPC范例,称为RFP,它提供更高的性能并且只能产生适度的移植成本; (3)我们设计并实现了一个名为Jakiro的内存键值存储来验证RFP的有效性。 实验结果表明,与Sever-Bypass和Server-reply相比,RFP在不同工作负载下将吞吐量提高了1.6×~4×。
在本节中,我们将讨论使用RDMA实现RPC的设计选择,然后是我们的两个观察结果,这些观察结果将导致RFP中的关键设计决策。
作为分布式应用程序中最常用的通信机制之一,RPC以隐藏基于消息的通信的复杂性而闻名于上层应用[14,25,27,34]。 目前,RPC的实现存在许多变化和细微之处,导致各种不同(不兼容)的RPC机制。 但是,典型的RPC调用总是包含三个步骤,如图2所示:(1)the Request Send客户端将函数调用标识以及参数发送到服务器(2)the Request Process请求处理步骤,在该步骤中处理请求以在服务器上生成结果; (3)the Request Return结果返回步骤,结果转移到客户端[2,6]。
表1说明了使用RDMA进行RPC调用时每个步骤的设计选择。对于步骤1,由于服务器不知道客户端何时可以调用RPC调用,唯一的选择是客户端使用Out-bound RDMA操作将请求发送到服务器。在这种情况下,服务器始终使用In Bound RDMA操作。根据服务器是否参与处理请求,步骤2有两个选择。如果涉及服务器,移植成本会降低。服务器回复遵循这种范例。Server-bypass不需要服务器处理请求,因此降低了服务器上的CPU利用率。成本是每个不同的应用程序需要特殊的数据结构来协调来自多个客户端的并发访问。步骤3还有两种选择,用于将数据从服务器传输到客户端。服务器可以通过从服务器发出Out-bound RDMA操作直接将结果发送到客户端,或者客户端可以通过RDMA读取(即,In-bound RDMA到服务器)从服务器的内存中获取结果,服务器分别采用Server-bypass和Server-reply。为了完整起见,表1列出了所有可能的设计选择,其中一个是没有意义的,即服务器不处理请求,而是使用Out-bound RDMA发送结果。
为了量化不对称性并研究其他属性(如可伸缩性),我们编写了一些微基准测试,并针对八台机器的集群运行它们。每台机器都配备了Mellanox ConnectX-3 InfiniBand NIC(MT27500,40 Gbps)[20]和双8核CPU(Intel Xeon E5-2640 v2,2.0 GHz)。这些机器的详细信息在第4节中介绍。我们选择一台机器作为服务器,其他机器作为客户机。这是典型的客户端-服务器体系结构。我们测量在服务器机器上发出Out-bound RDMA操作(即服务器向客户端发出RDMA WRITE)和服务器机器In-Bound RDMA操作(即,从客户端发出RDMA READ 请求)的IOPS。通过让服务器不断向其他7个客户端发出RDMA写操作来测试Out-bound IOPS。每个服务器线程随机选择一个客户端机器,并向其内存发出RDMA写操作,并在当前操作完成后重复此操作。类似地,通过让7个客户端向服务器发出RDMA读取操作来测试In-bound IOPS。客户端线程和服务器线程的内存缓冲区是独立的,不会相互影响。对于这两个测试,我们在每个客户端计算机上启动四个线程以使服务器的RNIC饱和。
为了模拟发出RPC请求的常见方式,而不是发出异步RPC请求,我们总是在开始下一个操作之前等待RDMA操作完成。 换句话说,不同的线程可以同时发出RDMA操作,但每个线程最多只处理一个操作。 正如许多现有工作[11,13]所讨论的那样,在不等待完成通知的情况下批量处理请求或发出几个RDMA操作可以提高性能。 但是,这些优化并不总是适用,并且超出了本文的主题。
图3显示了Out-bound RDMA操作和带有32字节数据的In-bound RDMA操作之间的IOPS差异。 我们看到InBound的峰值IOPS(11.26 MOPS)比OutBound(2.11 MOPS)的峰值IOPS高约5倍。 我们用我们拥有的所有三种RNIC(即ConnectX-2,ConnectX-3和ConnectX-4)重复这个实验,结果表明这种不对称性出现在所有这些不同版本的硬件上。
我们与Mellanox开发人员的进一步讨论解释了原因。 对于单边RDMA操作,接收/响应该操作(即In-bound )的一方的工作全部由RNIC的硬件处理; 而另一方提出此操作(即出境)需要在硬件和软件之间进行交互,以确保发送和完成操作。 因此,接收方(In-bound )的工作负载更轻,并且通过RDMA进行单个数据传输的处理速度更快。 作为我们推测的间接证据,其他双边RDMA操作(例如RDMA Send / Recv)不显示不对称性。
我们还评估不同客户端线程和不同数据大小下的IOPS,以研究其可扩展性。结果显示,当每个客户端上的线程数超过某个阈值时,服务器的In-bound RDMA IOPS会降低(参见图4)。这是因为在发出RDMA操作时,客户端会遇到一些软件争用(由互斥引起)和硬件争用(由使用多个队列对(QP)和完成队列(CQ)引起),因此输出IOPS不会在客户端上扩展,这会降低服务器的In-bound IOPS。图3显示了四个服务器线程(每个线程绑定到一个专用CPU核心)足以实现2.11 MOPS的峰值Out-bound 性能。这些现象进一步证明了我们的论点,即在发布RDMA操作的竞争客户线程之间存在某些争用,这限制了Out-bound RDMA的峰值IOPS。如图5所示,可以注意到,当数据大小大于2 KB时,In-bound RDMA和Out-bound RDMA在IOPS中执行相同,因为在这种情况下带宽成为瓶颈。相反,当数据大小小于2 KB时,In-bound RDMA明显优于IOPS中的Out-bound RDMA。
该研究表明,虽然Server-reply提供了良好的可编程性,但它的性能较低(最多2.1 MOPS),因为其IOPS受到服务器的Out-bound RDMA IOPS的限制。
Server-bypass允许客户端通过单边RDMA操作直接读/写服务器的内存,而不涉及服务器上的CPU处理。 这被认为是用RDMA构建高性能应用的有前景的方法[4,23,30,32]。 但是,随着CPU处理被绕过,应用程序必须依赖于特定的数据结构和算法设计来协调多个客户端,因为它们可能访问相同的内存区域,从而导致数据竞争! 因此,对传统RPC应用程序的支持很糟糕,编程也不容易(就像所有其他无锁数据结构和算法一样)。
此外,在需要多个RDMA操作来完成请求时,Server-bypass在许多情况下无法达到预期的良好性能。 以Pilaf为例,即使使用75%填充的3路Cuckoo哈希表,Pilaf中的客户端也必须平均花费3.2次RDMA读取操作进行元数据探测(找到键值对存储在服务器中的位置) 和数据传输以完成键值GET [23]。 它减缓了RDMA的性能提升。 更糟糕的是,如果没有服务器参与请求处理,客户端必须使用更多的RDMA操作来自行解决请求中的冲突。 如图6所示,当写入密集型工作负载[14,17,25]发生冲突时,由于涉及的RDMA操作数量增加,吞吐量甚至会降至1 MOPS以下。 这极大地限制了服务器旁路在各种应用中的使用。
基于上面的两个观察,本节介绍了远程提取范例(RFP)的设计,这是一种新的基于RDMA的RPC范例,它提供传统的RPC接口(因此对以前应用程序友好)以及比server-bypass和server-reply有着更好的性能。 基于以上两个观察结果,针对RFP做出两个设计决策。 首先,服务器应该处理请求而不是完全绕过请求,因此不需要特定于应用程序的数据结构或重新设计。 其次,客户端应通过RDMA Read远程获取结果,而不是由服务器发送,因此服务器只处理In-bound RDMA操作。
如表2所列,RFP提供了一个包含四个基本API的接口,即,client_recv和client_send,server_send和server_recv,类似于TCP / IP套接字提供的接口。 因此,只需用我们的原始TCP / IP套接字接口替换,就可以在RFP之上构建RPC机制,这很简单[2,6,34]。 正如我们稍后将在3.2节中讨论的那样,在使用RFP之前应该手动设置几个参数。但是,由于RFP使服务器处理从客户端发送的请求,因此它不依赖于特定于应用程序的数据结构,因此仅增加适度的移植成本。
图7说明了如何使用RFP。 在图的底部,客户端使用客户端发送通过RDMA Write将其请求发送到服务器的内存,服务器使用server_recv从本地内存缓冲区获取请求,然后处理这些请求,这与server-reply相同。 但是,与服务器回复的情况不同,服务器在处理请求后不会直接将结果发送回客户端。 相反,服务器调用的server_send仅将结果写入本地内存缓冲区,客户端负责使用client_recv通过In-bound RDMA读取从服务器内存远程获取结果。
总之,RFP结合了其他两种范式的优势,同时也避免了它们的弱点。 首先,RFP依靠服务器来处理请求,这1)避免了设计特定于应用程序的数据结构的需要,这意味着它可以用于适应许多应用程序而只需要适度的移植成本; 2)还解决了我们在2.3节中描述的Server-bypass放大问题
图8给出了使用RFP和Server-bypass来实现key-value存储的GET操作的示例。 从图8(b)可以看出,Server-bypass涉及更多步骤:它要求客户端探测元数据(第3行),从服务器获取数据(第5行),并通过校验和检查数据的正确性和完整性(第6行)。 如果服务器发现数据正在被修改,或者存在密钥冲突,则客户端必须重试(第10行)。 相反,如图8(a)所示,RFP只需要客户端发送请求并接收结果(第3~4行),这与服务器回复兼容。 更重要的是,使用Server-bypass的复杂性不仅体现在所需的步骤数量上。 上述特殊GET程序是专门为此目的而设计的,因此不能用于其他类型的应用。
其次,RFP不会在网络操作上浪费服务器CPU周期来发送结果,这与传统观点不同。 相反,服务器只将结果写入本地响应缓冲区,但要求客户端远程获取结果。 这消除了在服务器端使用Out-bound RDMA操作的瓶颈,这带来了比其他两个范例更高的性能。
由于RDMA要求使用的存储器注册到RNIC,因此RFP提供两个API,malloc buf和free buf(参见表2),以分配和释放由RFP自动注册到RNIC的缓冲区。客户端和服务器将消息直接放入malloc buf分配的请求/响应内存缓冲区中。当客户端将自身注册到服务器时,服务器和客户端都会记录请求/响应缓冲区的相应位置信息。因此,服务器和客户端都可以直接读/写其独占缓冲区,而无需进一步同步。如图7所示,每个缓冲区都有一个标题来表示状态(请求/响应是否已到达)及其大小。此外,在每个响应缓冲区中,标头还包含一个两字节的可变时间,以保持服务器对相应请求的响应时间。客户端使用此字段来更好地设置RFP原语的参数,这将在下一节中讨论。
为了最大化应用程序的吞吐量,RFP面临两个挑战:1)客户端应从服务器获取结果以减少不必要的RDMA操作; 2)客户端应该使用什么默认大小来获取结果,这样在大多数情况下只需要一个RDMA读取操作。
在我们的实现中,这两个挑战中的每一个都与参数选择问题相等。 因此,在本节的其余部分,我们首先展示如何将这两个挑战转移到参数选择问题中,然后我们提出了选择最佳参数的机制。
对于第一个挑战,straw-man设计反复从client_recv中的服务器响应缓冲区中获取结果,即两次重试之间没有任何间隔。在服务器端使用类似的方法,即服务器将重复检查其请求缓冲区以获取新请求。很明显,这种方法可用于实现最佳的可扩展性。但是,与我们假设它应该在请求处理中花费所有CPU周期的服务器不同,客户端可能还有其他职责,例如与用户交互。因此,这种简单的straw-man设计可能不是最佳的,因为它会导致客户端的CPU消耗更高,并且浪费服务器的In-bound IOPS,尤其是当平均重试次数很多时。因此,RFP使用混合机制在延迟,吞吐量和客户端CPU消耗之间实现良好的折衷。该机制从使用重复远程提取开始,然后如果检测到重试的数量大于某个阈值R则自动切换到服务器应答。当重试次数小于(或等于)R时,RFP使用重复远程提取以提供更高的吞吐量和更低的延迟。否则,与服务器回复相比,重复远程提取带来的吞吐量提高很少,并且RFP切换到服务器回复以节省客户端的CPU消耗。 R是第一个挑战的参数,其选择将在后面讨论。
对于第二个挑战,不同的RPC调用生成不同大小的结果,并且通常不可能预先预测大小。 RFP要求服务器在其响应内存缓冲区中填充每个RPC调用的结果大小,以供客户端获取,如图7所示。但是,如果在获取数据之前始终需要分离的RDMA读取来获取结果大小,则会很昂贵,这浪费了RNIC IOPS资源的一半。为了缓解这个问题,我们将结果连续存储在响应缓冲区中的标题之后,并为每个客户端设置默认的提取大小(表示为F)。当F不小于总响应大小时,客户端将通过一次RDMA操作从服务器内存中获取响应头和有效负载数据。只有当实际结果大小大于获取大小时,客户端是否需要发出另一个RDMA Read以获取剩余数据。此机制大大减少了用于RPC调用的平均RDMA操作数,尤其是当结果的大小通常较小时。 F是第二次挑战的参数。
Parameter Selection
使用R和F,我们将这两个挑战一起模拟为参数选择问题:R和F的选择在上层应用的吞吐量中起着重要作用。 在RFP中,吞吐量T由以下形式确定:
从等式中我们可以看出,RFP应用的吞吐量(T)与四个因素有关:
•R - 在切换到服务器回复模式之前从客户端读取RDMA的重试次数;
•F - 客户端用于从服务器读取远程结果的提取大小;
•P - 服务器上请求的处理时间;
•S - RPC调用结果大小;
在这些因素中,P和S仅与应用程序相关,而R和F与应用程序和RDMA硬件相关。 因此,我们首先要了解R和F如何与给定的硬件功能相关。 稍后,我们将讨论如何确定最佳R和F,以便通过将它们与P和S(即应用程序特性)连接来实现更高的应用程序吞吐量。
为了设计一个可以自动为应用选择最佳R和F的机制,我们分别研究调制这两个参数的影响,并观察使用方程来描述它们之间的关系很复杂,因此很难直接计算 最佳结果。 然而,基于枚举的方法足以解决优化问题,令人惊讶的是,我们发现最佳R和F的可能范围是有限的。
首先,图9显示了当请求的服务器处理时间变化时重复远程提取和服务器应答的吞吐量,F和S都设置为1字节,因此只需要一次RDMA读取操作来获取结果。 因此,无论F和S如何变化,吞吐量(MOPS)都是每个P的T的上限。 这是因为:(i)。 使F和S彼此不相等会导致需要额外的RDMA操作(当F S时);(ⅱ)。 当F(和S)增加时,吞吐量只会下降。
给定所有可能的F和S的P上限曲线,我们可以得到R的上界,即R应该在[1,N]内,其中N是RDMA读重试的上限数。 如果R> N,则重复远程提取的吞吐量改进受到限制,同时它比服务器回复占用更多客户端的CPU资源。 N的设置取决于硬件配置(类似于图9)以及开发人员关于他们对吞吐量改进和客户端CPU消耗之间权衡的期望的输入。 在这种情况下,我们选择N为5,根据上面的曲线将其映射到P为7的点。 这是因为当P≥7μs(10%以内)时,重复远程提取的吞吐量并不比服务器应答大得多,而客户端可能花费超过CPU消耗的两倍。
其次,图5显示了不同数据大小下RNIC的IOPS。 图中的曲线表示IOPS和数据大小之间的关系,可以分为三个范围:[1,L],[L,H]和(H,∞)。 由于RNIC中数据传输的启动开销,数据大小小于L(在第一范围内)不会增加吞吐量。 大于H的数据大小也不会增加吞吐量,因为此时带宽成为瓶颈并且随着大小的增加而线性地减小。 因此,F必须在第二范围[L,H]。 L和H依赖于硬件配置,可以通过运行一次基准测试得到(类似于图5)。 例如,在我们的RNIC(InfiniBand)配置中,L是256字节,H是1024字节。
基于上述观察,R和F的选择分别限制在[1,N]和[L,H]中,这意味着仅需要考虑(H-L)* N对候选者。 更重要的是,N和H -L都足够小,可以进行简单的枚举。 因此,RFP使用基于枚举的方法来确定bestRand F,其中使用以下等式进行比较:
具体而言,对于应用程序的每个结果,RFP计算其吞吐量(Ti)。 Ti的计算取决于取出尺寸(F),结果尺寸(Si)和R和F(IR,F)下RNIC的IOPS:如果F≥Si,Ti是IR,F; 如果F Discussion. 实现混合机制以在重复的远程提取和服务器应答之间切换还有两个细节。首先,客户端和服务器都为每对hclient id, RPC id维护一个模式标志,它指定当前的使用范例。此标志只能由相应的客户端修改(通过本地写入本地标志和RDMA写入服务器的标志),服务器通过检查其本地模式标志来了解当前范例。最初,该标志设置为重复远程提取,因此客户端将不断从服务器获取结果。如果失败的重试次数变得大于R,则客户端将模式标志(本地和远程)更新为服务器回复并将其自身切换到服务器回复,即等待直到从服务器发送结果。相反,如果客户端当前处于服务器回复中,它将记录最后的响应时间,如果发现响应时间变短,则切换回重复的远程提取。 RFP在响应缓冲区的标题中记录完成请求的响应时间(参见图7),客户端将通过RDMA读取来获取该响应时间。 其次,一些具有意外长的服务器处理时间的请求可能导致重复的远程提取和服务器应答之间的不必要的切换。 为了避免这种现象,RFP只有在发现预定义数量(例如两个)的连续RPC调用遭受5次远程提取重试失败时才切换到服务器应答。 否则,RFP将保持重复的远程提取模式。 根据第4.4.2节中的评估,只有0.2%的请求具有意外长的应用程序处理时间。 因此,两个(或更多)连续RPC调用很少会出现意外的长处理时间。 我们的评估回答了以下问题: •使用RFP的移植成本是多少? •RFP的性能优于Server-replay和Server-bypass? •RFP如何在不同的工作负载下运行? 为了评估应用程序如何轻松有效地使用RFP,我们实施了Jakiro,一种基于RFP的内存中Key-Value存储。 Jakiro包含两个主要模块:使用RFP进行RPC调用的通信协议,以及保持Key-Value对的内存中键值结构。 Communication Protocol: 在Jakiro中,服务器导出RPC接口(即PUT和GET),以便客户端操作键值对。 该过程严格遵循传统的RPC实践:客户端调用RPC调用存根,它进一步使用RFP原语将数据发送到服务器。 服务器调用RPC回复存根,它将响应存储在存储器中,等待客户端获取它,或者在RFP自动切换到服务器应答模式时将其传输到客户端。 虽然内部实现完全不同,但Jakiro使用RFP,因为它是一个常见的RPC库。 In-Memory Key-Value Structure. 我们目前通过在内存中为其他应用程序缓存键值对来构建Jakiro(类似于Memcached [21])。内存中的结构包含许多存储桶,每个存储桶包含8个插槽4.插槽用于保存键值对的信息(例如保留该对的存储器地址)。当存储桶已满时,我们会在此存储桶中使用严格的LRU(最近最少使用)策略进行插槽驱逐。在Exclusive Read Exclusive Write(EREW)[18]中,整个结构被划分为不同的服务器线程。每个服务器线程只访问自己的数据分区。正如[11,18,22]之前的工作所证明的那样,这种设计能够为处理键值对提供高性能。我们在大约3,000行C ++代码中实现Jakiro。 在RFP中用于RDMA转移的底层库是由Mellanox OpenFabrics Enterprise Distribution [20]提供的rdmacm和ibverbs。在Jakiro中,服务器和客户端线程都直接轮询内存缓冲区和RNIC以获取消息发送/接收事件。同时,每个服务器线程完成消息打包/解包,发送/接收以及请求处理的所有工作。 Different Queue Pair Types.有三种队列对类型可用于支持RDMA。与所有服务器旁路解决方案一样,RFP需要使用可靠连接(RC),因为它是唯一支持单侧RDMA-Read和RDMA-Write的队列对类型。另外两种队列对类型,即不可靠连接(UC)和不可靠数据报(UD),只提供不可靠的传输服务,因此不能保证另一方接收消息:损坏和静默丢弃都是可能的。此外,它们仅支持有限的API(UC不支持RDMA-Read,而UD既不支持RDMA-Read也不支持RDMA-Write),这禁止用户减轻服务器处理数据包的负担。有些作品可以构建键值存储 UDand UC,例如HERD [11]和FaSST [12],它们可以实现比基于RC的解决方案更高的性能。这是合理的,因为可靠保证机制本身会带来一定的开销,但是需要应用程序来处理许多微妙的问题,例如消息丢失,重新排序和重复。考虑到直接的结果,即使现实世界中很少发生这种微妙的问题[12],也不能简单地忽略它们。此外,由于这些基于UD和UC的方法要求服务器将结果发送回客户端,因此当IOPS非常高时,消耗的服务器CPU周期可能成为瓶颈。图13和20还表明Jakiro实现了更好的延迟,因此RFP更适合对延迟敏感的应用程序。 Anuj等。 [13]也提出了使用RDMA的指南,它提供了许多有用的优化技术。但是,本文提出的主要技术,如门铃批处理,只能用于基于UD的解决方案。与硬件相关的其他技术与我们的范例正交,因此它们可用于进一步提高RFP的性能。 Different Paradigms.。其他现有的基于RDMA的解决方案通常应用服务器回复[7,9,10,28,31,33,34],服务器旁路[4,30,32]或这两种范式的组合[23,24] 。正如我们在第4节中所展示的那样,RFP可以比这两种传统范例更快,因为它1)仅在服务器端使用入站RDMA; 2)避免“bypass访问接入放大”问题。在那些基于服务器旁路的应用程序中,通常需要多个RDMA操作(3~6)来完成请求[23],当来自多个客户端的冲突很大时,该数字甚至可以更高。 对于那些使用RPC的遗留应用程序,RFP也只涉及适度的迁移开销,因为它不需要任何特定于应用程序的数据结构。相比之下,Pilaf和C-Hint必须提出推理数据一致性的解决方案[23,30]。 DrTM依赖显式锁和高性能HTM进行数据竞争协调[32]。 FaRM [4]也是一个采用服务器旁路的内存分布式计算平台。据报道,它能够以20台机器每秒执行1.67亿次键值查找(即每台服务器每秒约8M次请求),这比Jakiro大。然而,为了实现这种性能,FaRM使用Hopscotch哈希导致类似“批处理请求”的内容。使用FaRM,客户端需要获取N *(Sk + Sv)数据以获得单个键值对,其中N通常大于6,Sk和Sv分别是键和值的大小。因此,1)FaRM获得具有16字节密钥和32字节值的键值对的平均延迟为35μs,比Jakiro高约5倍; 2)如果仅使用N个获取的键值对中的少数数据,将浪费大量带宽和MOPS。 此外,必须提到的是,对于Pilaf,C-Hint和FaRM,所有这些都使用服务器回复来服务PUT请求。在这种情况下,这些系统遭受服务器出站RDMA的有限性能。 本文提出了一种新的基于RDMA的范例RFP,它支持传统的RPC接口并提供高性能。 RFP的设计基于两个观察结果:第一个是RNIC中的性能不对称,第二个是由于服务器旁路中的冲突解决而导致的性能下降。 通过使服务器参与请求处理,RFP能够支持传统的基于RPC接口的应用程序。 通过反直觉地使客户端从服务器的内存中远程获取结果,RFP可以充分利用服务器的入站RDMA,从而实现更高的性能。 实验表明,与服务器回复和服务器旁路相比,RFP提高了1.6×~4×。 我们相信RFP可以集成到许多基于RPC的系统中,以便不费吹灰之力地提高性能。4. Evaluation
4.1 An RFP-Based Application
5. Related Work
6. Conclusion