目录

  • 数据中心的RPC可以既通用且快
    • 作者要达成什么目标?
    • 基本思路
      • optimize for the common case
    • 关键数据结构:msgbuf
    • msgbuf的race condition
    • Wire protocol
    • 拥塞控制
    • 优化
      • 以下3个优化都在第5.2.2节
    • 参考

数据中心的RPC可以既通用且快

这篇是2019年NSDI会议的最佳论文[1]。看到6.824的2020年课程也即将讲这篇文章,安排在明年4月17日。这里先自己试着读一下。

作者要达成什么目标?

  • 不用特殊的硬件。(比如RDMA,比如不丢包的网络,比如FPGA)——只用普通的网卡,普通的交换机,达到高速RPC。

    • 小消息速率快
    • 大消息带宽高
    • 能上规模scales well
  • 可以很通用——可以作为一个drop-in的网络库,直接用在现有的软件中。
  • 在UDP(或者InfiniBand的不可靠数据报传输协议)之上实现。能处理丢包、网络拥堵、RPC请求在背景执行(异步?)。

基本思路

optimize for the common case

  • 针对普通情况(common case)做优化。对于小概率事件则不优化,故而导致小概率事件发生时可能更慢。
  • 普通情况的假设是:
  1. 网络不丢包(不需要重发)。
  2. 消息都很小——1个UDP包就装得下。
  3. 网络不拥堵。
  4. RPC处理程序都很小。
  • 疑问:刚才不是说不用特殊硬件吗?怎么又假设网络不丢包?

    • 答:数据中心内会丢包都是因为交换机缓冲区满了!eRPC限制每台机outstanding的网络流量,最多不能超过带宽延迟乘积(19k)。这既保证了用满带宽,又足够小,不会造成交换机缓冲区(12MB)满——也就极少会有丢包情况发生。

关键数据结构:msgbuf

消息缓冲区。

  1. 支持DMA。用户程序、eRPC和网卡共享这块内存。
  2. 零拷贝。就是说CPU不需要把数据从内存的一个区域拷贝到另一个区域。应用程序将数据写入到msgbuf以后,数据由网卡以DMA方式直接读取。
  3. 1个msgbuf存放1条消息。这条消息可以是单个UDP包,也可以是多个,根据消息长度决定。假定通常情况是1个包的小消息。

    这张图解释了msgbuf的排列。
  • 数据区是连续的,所以应用程序只要把数据区当成一个连续区域,尽管放数据就好了。
  • 如果1个UDP包无法发送完整个RPC request,数据区就会被拆分成N块(Data1Data_1Data1​,Data2Data_2Data2​……)。每块需要自己的UDP header:就是图中的H1H_1H1​,H2H_2H2​,……
  • 这样的设计是优化短消息——即只要1个UDP包就可以发送的消息。它只要1次DMA就能读取H1H_1H1​和Data1Data_1Data1​。(图中的a)如果是长度超过1个UDP包的长消息,从第二个包开始每个要2次DMA,一次读header,一次读数据(图中的b和c)。

msgbuf的race condition

  • CPU和网卡都要用msgbuf。必须确保两者不同时使用。
  • 好消息:当不丢包时,两者不会冲突。
  • 会出问题的情况:消息重发时。CPU重发(重新将msgbuf的引用加入到网卡的发送队列中。)此时网卡收到先前第一次发送同1条RPC的回复,并调用它的callback(应用程序的一部分)。接下来,应用程序执行callback可能会reuse这个msgbuf,而它的引用还在网卡发送队列中,网卡也会读取它的内容,这就是race condition。
  • 所以,必须避免以上情况。这就要求:在调用callback前,一定要确保该条消息的msgbuf引用已经不在发送队列中——即这条消息已经被网卡DMA读取。所以我们需要知道DMA完成的通知。
    • 传统做法:网卡在每次DMA完成的时候通知——但是慢25%。

      • if you set the RS bit in the command field of a transmit descriptor, then, when the card has transmitted the packet in that descriptor, the card will set the DD bit in the status field of the descriptor. If a descriptor’s DD bit is set, you know it’s safe to recycle that descriptor and use it to transmit another packet. [2]
    • eRPC的优化做法:不用DMA完成通知。如果我们收到server的RPC reply,我们就知道RPC请求已经发出了并被成功处理并返回了。如果没收到reply,就重发,但是重发时我们要阻塞,直到整个发送队列都发完(flush the TX DMA queue),包括这条重发本身。这就是把重发作为特殊情况。特殊情况下反而更慢。只对一般情况(不重发的)做优化。

Wire protocol


采用的是客户端驱动的方式——服务器端不主动向客户端发包,每一条服务器端发送的包,都对应1条客户端包。
这样做的目的是1. 重传的时候只要客户端自己决定,不用与服务器协调。2. 限流器可以只设立在客户端。
上图左侧是普通的单封包的 RPC请求和回复。
上图的右侧是1条包含3个包的RPC请求(蓝色),它的回复也是3个包(红色)。回复的发送比较费劲:第一个包发出后,服务器不能继续发了。要等客户端发来request-for-response,然后才能继续发出第二个包。这就是客户端驱动带来的麻烦。

拥塞控制

根据经验研究,数据中心的网络90%~99%以上的时候都是不拥堵的。所以针对common case优化就是绕过拥塞控制、绕过限流器。
拥塞控制用的是Timely [3]
限流器用的是Carousel [4]

疑问:这张图连续2个判断中都有TX rate == MAX?如果能通过第一判断,就说明TX rate必须等于MAX,那么怎么可能下一个判断不成立?

优化

文章最终使速度提升了66%,这是叠加了许多个优化的结果。

  1. 采用“dispatch”线程周期性地执行endpoint的事件循环(eventloop)。这样就是单线程的,不需要线程间通讯。(At datacenter network, interthread communication is expensive.)
  2. 利用比较新的网卡特性:multi-packet RQ descriptor。在接受队列中1个描述符能指向连续(contiguous)存放在内存里的多个packet buffers。(4.1.1节)
  3. 零拷贝的发送和接受。零拷贝意味着CPU和NIC要共享这块内存区域。要避免race condition。服务器端接收RPC请求,网卡做DMA将数据包写入内存,解析来是eRPC要把这个内存地址交给RPC handler,且在RPC handler处理完之前,这块内存区域不能被网卡改写。即:指向它的描述符暂时不能被重复使用。(4.2.3节)
    疑问:传统做法是怎样?
  4. 服务器端发送RPC reply用的msgbuf不用每次动态分配,可以预分配固定的msgbuf。这是针对短reply的优化。(4.3节)
以下3个优化都在第5.2.2节
  1. 绕过Timely拥塞控制。
  2. 绕过Carousel限流器。
  3. batched timestamps for RTT measurement。减少调用rdtsc()获取时间的次数。

参考

[1] https://www.usenix.org/conference/nsdi19/presentation/kalia
[2] https://pdos.csail.mit.edu/6.828/2018/labs/lab6/
[3] TIMELY: RTT-based congestion control for the datacenter
[4] Carousel: Scalable traffic shaping at end hosts
[5] ixy - 1000行代码的用户空间网卡驱动

分布式系统:FastRPC eRPC相关推荐

  1. 分布式系统 一致性模型的介绍 以及 zookeeper的 “线性一致性“ 讨论

    文章目录 1. 一致性 概览 1.1 分布式系统的 "正确性" 1.2 线性一致性(Linearizability) 1.3 顺序一致性(Sequential consistenc ...

  2. 《异步处理在分布式系统中的优化作用》学习笔记

    原文地址:http://www.infoq.com/cn/presentations/optimization-of-asynchronous-processing-in-distributed-sy ...

  3. Travis CI : 最小的分布式系统(三)

    日志的作用有两个:当构建日志的数据块通过消息队列进来时,更新数据库对应行,然后推送它到Pusher用于实时的用户界面更新. 日志块以流的形式在同一个时间从不同的进程中进来,然后被一个进程处理.这个进程 ...

  4. Travis CI : 最小的分布式系统(一)

    (本文翻译自http://www.paperplanes.de/2013/10/18/the-smallest-distributed-system.html,由@金斌_jinbin 翻译) Trav ...

  5. 整理下.net分布式系统架构的思路

    最近看到有部分招聘信息,要求应聘者说一下分布式系统架构的思路.今天早晨正好有些时间,我也把我们实际在.net方面网站架构的演化路线整理一下,只是我自己的一些想法,欢迎大家批评指正. 首先说明的是.ne ...

  6. 如何选择分布式系统(区块链)协议?

    链客,专为开发者而生,有问必答! 此文章来自区块链技术社区,未经允许拒绝转载. 如何选择分布式系统(区块链)协议? 在构建包分布式系统功能的应用程序时,<财富>500强企业和创始人经常问我 ...

  7. 分布式系统的时间顺序

    链客,专为开发者而生,有问必答! 此文章来自区块链技术社区,未经允许拒绝转载. 分布式系统的时间顺序 区块链被认为是分布式的系统,分布式系统中由于多节点,通讯.物理位置等的问题,各节点间时间一致的问题 ...

  8. 分布式系统中节点之间的同步形成区块链

    链客,专为开发者而生,有问必答! 此文章来自链客区块链技术问答社区,未经允许拒绝转载. 分布式系统中节点之间的同步形成区块链 分布式系统由Tanenbaum定义,"分布式系统是一组独立的计算 ...

  9. 工作中感受到的消息中间件在分布式系统中的使用场景

    经历 以前在qunar实习,第一次接触消息中间件,那时候概念还不清楚,朦朦胧胧有个初步认识,现在正式工作了,又一次接触了消息中间件,初步总结几种场景. 场景 1.分布式系统中,不同系统之间传递消息. ...

  10. 美团即时物流的分布式系统架构设计

    背景 美团外卖已经发展了五年,即时物流探索也经历了3年多的时间,业务从零孵化到初具规模,在整个过程中积累了一些分布式高并发系统的建设经验.最主要的收获包括两点: 即时物流业务对故障和高延迟的容忍度极低 ...

最新文章

  1. python打包为exe文件_Pyinstaller(python打包为exe文件)
  2. Python的sorted函数应用
  3. [Java] 接口(Interface)与 抽象类 (Abstract)使用规则和区别
  4. 每日一皮:程序员最讨厌的四件事!
  5. 【BZOJ-2669】局部极小值 状压DP + 容斥原理
  6. IOS开发网络第一天之06线程之间的通信
  7. Linux 命令之 w 命令-显示目前登入系统的用户信息
  8. 基于Verilog语言的伪随机码的编写
  9. 大数据毕设/课设 - 基于大数据的医疗与疾病监控大数据可视化设计与实现
  10. while在Java用法_while和do-while的使用方法
  11. Deepgreen/Greenplum删除节点步骤
  12. 《Linear Graph Convolutional Model for Diagnosing Brain Disorders Zarina》阅读笔记
  13. 新浪微博用户密码泄露 经部分用户验证为真
  14. mysql 表情符号 用什么类型_使MySQL能够存储emoji表情字符的设置教程
  15. 治五气,艺五种,抚万民,度四方
  16. Processing摸索前行(9)-音频可视化
  17. style.left和offsetLeft 用法
  18. 迷惑,不知何去何从。。。。。
  19. 计算机可用内存分配失败,安装内存和实际可用内存不一样什么原因
  20. 2009.09.30 随想

热门文章

  1. php 后台实现订单支付成功后语音提示
  2. PHP-FPM 性能优化
  3. 13 . 外部中断实验
  4. 美国金融危机产生的原因
  5. uboot中bss的理解
  6. APSINx010HC系列射频模拟信号发生器—输出高达6.1GHz
  7. 计算机表格斜杠怎么打,如何在excel表格中绘制斜线并上下打字
  8. poi导出Excel,表格画斜线,并设置数据
  9. 黑灰产套现城市消费券大揭秘
  10. Codeforces Round #459 (Div. 1) B. MADMAX(博弈+DP+记忆化搜索)