eRPC:Datacenter RPCs can be General and Fast

nsdi19    Carnegie Mellon University

简介

作者提出现有的数据中心的软件都是通过牺牲通用性或高性能来获得另一个便利,例如RDMA牺牲了通用性实现了高性能。于是,作者认为这样的做法是没有必要的,继而提出了eRPC,兼顾通用性和高性能两种需求的RPC库。eRPC可以运行在有损网络中,不用修改网卡或交换机也能在多个场景中实现与专用解决方案近似的性能。

作者提出一些专用的方案由于缺乏规范的说明,不能对现有的软件进行重用,重新部署比较复杂,使得传统的开发商渐渐放弃,重新使用基于linux内核的TCP协议栈。通过eRPC作者也想说明端到端的解决方案比增加额外的网络功能更有效和通用。

eRPC提供了三种性能特性:(1)对短消息提供高效的消息速率(2)对长消息提供高带宽(3)对不同的节点数和CPU核数提供高扩展性。此外,它还提供了丢包、节点失效、拥塞控制和长时间运行的背景请求的处理机制。

eRPC的主要贡献:(1)设计和实现了eRPC库。其中包含了对普通场景的优化,在出现重传、节点失效、限速情况下的零拷贝传输技术,以及对可扩展性的支持。(2)在无损网络上做了实验,结果非常好(3)可以作为网络内的一个库与现有软件兼容,实现高性能。以Raft为例,并与可编程交换机(NetChain)、FPGA和RDMA做了性能对比。

背景和动机

eRPC使用基于轮询的用户空间网络I/O,通过限制每条流的发送数据包数在一个BDP来避免丢包。

无损网络:无损网络是链路级的网络特性,一般用于支持RDMA。但由于PFC带来的大量问题,数据中心操作员不愿意部署PFC,于是出现了IRN。作者表明eRPC中的BDP策略也是受到IRN的启发,但与IRN不同的是,eRPC不需要RDMA网卡的支持。

交换机缓存远大于BDP:数据中心带宽的增加,RTT的减少,使得BDP减小,但交换机缓存一直在增大。并且,现有的交换机缓存是动态共享的,比如说在incast场景下,可以将大部分缓存都分配给incast port,避免缓存溢出引起丢包。根据计算,在交换机缓存为12MB,BDP为19KB的情况下,理论上可以支持incast场景下的640条同时连接。在实际场景中,我们希望交换机可以同时支持50条左右的连接,目前的拥塞控制机制例如DCQCN可支持20条,Timely可支持40条左右连接,这与理论上的640条都相差甚远。作者表明eRPC这种机制(限制每条流的传输数据包数量)可以使交换机可以支持不同BDP和不同的交换机缓存,更具有通用性。

已有专用解决方案的限制:(1)都在性能或通用性上做了牺牲,应用不能充分利用网络。这些与应用结合的专用系统只能适用于特定的场景,要求专用硬件支持,缺乏通用性。(2)并且,在落地时,对于厂商来讲,重新设计、实现、部署和管理新型应用会消耗大量的人力物力。(3)除此外,作者还提出在一些特定场景下,专用解决方案的高性能优势也不复存在。例如,在key-value存储和分布式处理应用上,RPC的表现优于RDMA的表现。作者分析原因为,在这些系统的操作中,需要多次的远端内存访问,使用RPC只需要一条连接就可以完成,而RDMA需要建立多条连接才能完成。在下文中,作者将会从“复制”这个应用上说明通用的RPC方案的性能与专用的基于交换机和FPGA的方案同样具有可比性。

eRPC综述

主要介绍eRPC的线程模型和API,eRPC实现在传输层(只提供不可靠的基础的packet I/O)之上,需要用户空间网卡驱动。

RPC API:

RPC调用最多执行一次,并且是异步的(不用等待调用结果,非阻塞式),避免网络状态对性能的影响。用户存储RPC信息的地方叫做msgbuf。每个用户线程在发送或接收RPC时都会创建一个单独的endpoints。每个endpoints包含一个RX、TX、event loop和几个session。一个session连接两个Rpc endpoint(例如,两个用户线程)。一个用户线程可以参与多个session,担任不同角色。

用户线程的角色类似于调度线程,它周期性的运行endpoint的event loop,同时也可以调用请求处理器(request handler),或者将长时间运行的请求处理器调度给工作线程(work thread)。

工人线程:

对一个RPC系统来讲最关键的设计是决定哪个线程运行RPC处理器。一些RPC系统仅使用调度线程用于网络I/O,调度线程通过调度让工人线程运行请求处理器。但在数据中心中,线程间通信是非常昂贵的,会增加400ns的请求时延,降低吞吐量。还有一些系统为避免进程间通信的开销,让调度线程处理所有的请求处理器。这种方法在执行长请求处理器时有两个缺点,一是长请求处理器会锁住其他的调度处理操作,增加尾部时延,二是他会阻止服务器和客户端之间的拥塞快速响应,这是因为服务器在运行用户代码时不能发送数据包。

为求平衡,eRPC允许在调度和工人两种线程上运行请求处理器。具体由谁来运行请求处理器,在注册请求处理器时,由用户输入决定。

eRPC设计

作者主要介绍了三个方面的设计:网络的可扩展性、在支持零拷贝中遇到的挑战、session的设计。同时,eRPC还优化了普通场景,例如当在调度线程上运行请求处理器时,RPC通常是比较小的(避免长请求),并且网络时不拥塞的(避免慢拥塞响应带来的弊端)。

可扩展性考虑:

由于RDAM将连接信息缓存在网卡上,网卡的存储空间有限,当连接节点数增大时,扩展性成为问题。对于传统的用户空间数据包I/O,网卡收到数据包后将数据包净核写入由RX描述符制定的内存区域中,RX描述符是由接收端主机预先发布的。如果RX中没有描述符(可理解为令牌),则数据包会被丢弃。网卡将数据包净核写入指定区域后,会在主机的RX completion queue添加一条entry,接收端主机会定时检查RX completion queue的头部查看是否有新接收的数据包。

为了避免因没有描述符而引起的丢包,RQ的大小设置应当与连接的RPC endpoints数成比例。但是旧的网卡在设置了较大的RQ的情况下会出现缓存颠簸(cache thrash,指由于对内存资源的过渡利用使进程进行不下去,然后不断尝试重复同一动作带来的高CPU消耗等现象,https://searchsoftwarequality.techtarget.com/definition/cache-thrash),新的网卡由于对RQ描述符预取和缓存更加准确,使得这一现象得到缓解。

作者提出以一种新颖的方式利用现有网卡的特性(多包RQ描述符可以确定几个相邻的数据包缓存块),保证每个CPU核可以处理的固定的网卡内存。这可以简化未来网卡的设计(不再需要RQ描述符缓存),但由于目前网卡都支持很大的RQ,所以此方式只能在一定方式上提升性能。

RDMA的扩展限制:

RDMA将连接信息存储在网卡上限制了可扩展性。当多个CPU核共享一个网卡时,可存储的连接数量将会降低,并且CPU性能也会降低。业内网卡开发人员设想,通过不断提高网卡的性能可以实现可扩展性,但投入了大量的时间成本和金钱成本后,市场反响并没有预期的那么好。并且随着多主机网卡(即允许2-4个CPU共享一个高性能网卡)的趋势到来,加剧了RDMA网卡的可扩展性问题。

eRPC采取CPU管理连接连接状态的方式,因为CPU是通过DRAM存储的,空间更大,产生cache miss的概率也低。

零拷贝传输的挑战:

消息缓存的布局:作者重新设计了消息的排列顺序,将多包短消息重组为单包短消息,使得在一个DMA周期内就可以读完短消息。

消息缓存的所有者问题:在eRPC中,客户端发送完请求消息后就会将msgbuf还给应用,之后在队列中应不会出现任何有关请求消息的排队,msgbuf也不会被请求消息所占用。当客户端收到并处理回复消息时,会调用连续函数,产生complete消息,重用request msgbuf,发送给服务器端。问题出在当客户端误判请求消息被丢失时,request msgbuf同时出现回复消息和请求消息,此时就会出现msgbuf所有者冲突问题。解决方案作者说会在附录中说明。

DMA操作完成通知方式:传统的做法是在DMA操作完成后使用信号包在TX完成队列中添加一条表项,标志DMA操作完成。作者认为信号包的方式增加了网卡和PCIe资源的占用,所以提出使用非信号包的传输模式。作者秉持让普通模式(无重传)下的DMA操作更快,特殊模式下调用更昂贵的方式处理的理念。当遇到重传请求包在TX DMA队列中排队时,就刷新该队列,此时会阻塞,直到队列中所有的数据包都完成了DMA化。此刷新操作只会在发生节点失效或重传等特殊情况下才会执行,因此从整体上看,使用非信号包传输DMA完成消息的方式的性价比更高。

消息缓存的布局

零拷贝请求处理:Zero-copy reception is harder than transmission: To provide a contiguous request msgbuf to the request handler at the server, we must strip headers from received packets, and copy only application data to the target msgbuf. However, we were able to provide zero-copy reception for our common-case workload consisting of single-packet requests and dispatch-mode request handlers as follows. eRPC owns the packet buffers DMA-ed by the NIC until it re-adds the descriptors for these packets back to the receive queue (i.e., the NIC cannot modify the packet buffers for this period.) This ownership guarantee allows running dispatch-mode handlers without copying the DMA-ed request packet to a dynamically-allocated msgbuf. Doing so improves eRPC’s message rate by up to 16%.(看不懂)

会话

每个会话都会维持多个未完成的请求连接,同时对一个会话的请求是互相独立的,无序的。这避免了在长请求的工人模式RPC下的调度模式RPC的阻塞。eRPC中支持每个会话的同时请求数为8,当超出限制时,请求将排队等待。每个会话会使用一组slots跟踪未完成的请求的RPC元数据。在服务器模式下的会话slot会被分配一个MTU大小的msgbuf,用于请求处理器处理较短的回复信息。

会话令牌:eRPC中限制了一个session中传输中的数据包数量,一是为了避免由于RQ中没有描述符而引起的丢包(发往同一个RPC的数据包数量不能操作其RQ的大小),二是为了实现会话令牌的自动端到端流控,从而避免数据包在交换机中的排队。当每个session允许的令牌数量为BDP/MTU时,每个session就可以实现线速发送,这种情况针对具有高吞吐量需求的应用。当令牌数量设置为较小值,例如1时,对应的是具有低时延需求的应用。

考虑到会话的可扩展性,主要取决于用户需要的令牌数量,RQ的大小以及主机可支持的RQ大小。目前的网卡可以支持多个大的RQ,所以网卡不再成为会话可扩展性的限制。由于每个RQ的表项都需要主机为其分配一块数据包缓存,所以过大的不必要的RQ还会浪费主机内存,应避免。

有线协议(wire protocol)

作者专门为eRPC设计了通信协议,用于优化短的RPC,支持会话令牌限制操作。为了简化,作者选用简单的客户端驱动协议,也就是说服务器端不会主动发送包,只会根据客户端发送的数据包作出反馈。只有客户端会维持协议状态,当发生重传时会进行状态回滚。

协议消息

一个会话两个令牌

对于单数据包的RPC请求,其credit return包会随着Response data消息隐式返回给客户端。 对于多数据包请求,非尾包的credit return包会立即显式返回,尾包的credit return会随着第一个response data消息隐式返回给客户端。在发送第一个response data后,服务器端不会主动发送剩余的response data,直到收到request for response包后,才发送后续的response data,并且也是一对一触发的模式。

这种客户端驱动的协议缺点是增加了多包请求的响应时延。作者解释这种增加的时延随着请求包数量的增加不会超过回复时延的20%。并且,对于eRPC来讲,在用户空间发送额外的CR或RFR包的开销是很少的,所以不打算优化协议。但如果要将其实现在内核态上,要进行协议优化,因为在内核上发送16B大小的包与发送MTU大小的包的CPU开销是差不多的。

拥塞控制

作者主要想法是在软件上实现与硬件性能差不多的拥塞控制算法。基于通用硬件的拥塞控制算法有Timely和DCQCN,并且都在大规模数据中心中应用了,所以作者尝试将其用软件实现。由于实验环境中交换机不支持ECN标记,所以最后作者选定将Timely实现在eRPC方案中。eRPC可以完美实现Timely的三个组件:对单个数据包的RTT测量,基于测量RTT进行速率计算,速率控制(eRPC是基于客户端会话的)。对于仅运行在服务器模式的RPC endpoints,拥塞控制机制不会引入任何开销。

普通场景下的优化:作者提出了三个普通场景下的优化策略来优化eRPC在普通场景下的性能。前两个优化策略是基于“数据中心在大多数情况下是不拥塞的”这一条件的,随后作者给出了两篇论文的数据证明这一条件成立。

当一个会话是不拥塞的,那么测得的RTT值将会很小,Timely计算出来的速率也将保持在链路最大速率上,我们将这样的会话称之为不拥塞的。

三个策略:(1)timely bypass:当一个不拥塞会话收到的数据包的RTT低于Timely设定的最小门限时,不更新速率。(2)Rate limiter bypass:对于不拥塞会话,不需要将数据包放入速率限制器上发送,而是直接发送。(3)Batched timestamps for RTT measurement:在测量RTT时调用函数需要花费8ns的时延开销,这一开销是不可避免的,因此作者将对每个数据包都进行RTT测量优化为对每一个RX或TX新到达的分析进行采样测量。

与IRN的比较:作者分析说IRN的性能实验是基于仿真交换机的,每个端口的交换机缓存是静态的,微小的。对于缓存资源匮乏的设置来讲,SACK的实现对于性能是非常必要的。然而,动态缓存交换机目前已经在数据中心中广泛部署了,基于一个BDP的流控已经使得丢包概率非常小,所以作者表明没有在eRPC中实现SACK,还有一个原因就是SACK的实现太复杂了。

丢包处理

eRPC为简化设计,对于重排序的包采用丢弃的处理方式。作者表明由于数据中心中使用ECMP做负载均衡策略,出现乱序丢包并不少见,这也不是造成性能损失的主要原因,并且现有的RDMA网卡对于重排序包也是采取丢弃方式。

当判断丢包后,客户端会使用go-back-N机制将请求包的状态回滚,重新声明credit,重传请求包。服务器端对于同一个请求只会调用一次请求处理器,保证了RPC最多执行一次的原则。当出现误判时,比如没丢包被判定为丢包,客户端就会违背令牌协议,客户端发往服务器端的数据包数量就超出了令牌限制。在极端情况下,这种误判可能导致服务器端的RQ描述符被占满,造成真正的丢包。作者表明eRPC允许这种情况的发生,并且会将被迫丢包当做真正的丢包处理。

你可能感兴趣的:(eRPC:Datacenter RPCs can be General and Fast)