聊聊消息队列高性能的秘密——零拷贝技术

前言

RocketMQ为什么这么快、Kafka为什么这么快?用了零拷贝技术?什么是零拷贝技术,它们二者的零拷贝技术有不同吗?

为什么需要零拷贝

在计算机产业中,I/O的速度相较CPU,总是太慢的。SSD硬盘的IOPS可以达到2W、4W,但是我们CPU的主频有2GHz以上,也就意味着每秒会有20亿次的操作。如果对于I/O操作,都是由CPU发出对应的指令,然后等待I/O设备完成操作之后返回,那CPU有大量的时间其实都是在等待I/O设备完成操作。 但是,这个 CPU 的等待,在很多时候,其实并没有太多的实际意义。我们对于 I/O 设备的大量操作,其实都只是把内存里面的数据,传输到 I/O 设备而已。在这种情况下,其实 CPU 只是在傻等而已。特别是当传输的数据量比较大的时候,比如进行大文件复制,如果所有数据都要经过 CPU,实在是有点儿太浪费时间了。因此计算机工程是们就发明了DMA技术,也就是直接内存访问(Direct Memory Access)技术,来减少CPU等待的时间。

DMA技术

本文不做过多相关介绍,这里我简单总结下对它的理解。
如上所述,CPU资源很宝贵,如果用它来处理I/O那么将是极大的损失,比如说我们用千兆网卡或者硬盘传输大量数据的时候,如果都用CPU来搬运的话,肯定是忙不过来,所以可以选择DMAC(DMA控制器即DMA Controller,简称DMAC),CPU告诉DMAC它需要传输什么数据,从哪里传输,传输到哪里去这些信息,然后交给DMAC去做,DMAC可以等到数据都到齐了,再发送信号,交给CPU去处理,而不是让CPU在哪里忙等待。( DMAC:我们不加工数据,只是数据的搬运工
具体传输过程(从磁盘传输到网络)如图:

聊聊消息队列高性能的秘密——零拷贝技术

零拷贝

如上我们发现,虽然通过DMA技术能够使得CPU不用忙等待I/O操作,减轻了一些压力,但是从图中也能清晰地看出,两次CPU的Copy完全是在搞笑的,能不能把这两个步骤去掉呢?这就是零拷贝需要做的事情了,而我们熟知的RocketMQ、Kafka都是使用了零拷贝技术来优化I/O,而它们的零拷贝处理方式却有些不同。

Kafka零拷贝——SendFile

Kafka的代码调用了Java NIO库,具体是FileChannel里面的transferTo方法(底层是。我们的数据并没有读到中间的应用内存里面,而是直接通过Channel,写入到对应的网络设备里。并且对于Socket的操作,也不是写入到Socket的Buffer里面,而是直接根据描述符(Descriptor)写入到网卡的缓冲区里面。于是,在这个过程中,只进行了两次数据传输。(由于没有在用户态内存层里面去Copy数据,干掉了两次CPU的Copy,所以我们将之称为 零拷贝(Zero-Copy)

SendFile的工作原理

系统调用sendfile()通过DMA把磁盘数据拷贝到kernel buffer(read buffer),然后数据被kernel直接拷贝到另外一个与socket相关的kernel buffer(socket buffer)。这样就没有用户态和内核态之间的切换,从内核中直接完成了从一个buffer到另一个buffer的拷贝,因为数据就在kernel里。
如图:
第一次,是通过 DMA,从硬盘直接读到操作系统内核的读缓冲区里面。第二次,则是根据 Socket 的描述符信息,直接从读缓冲区里面,写入到网卡的缓冲区里面。

聊聊消息队列高性能的秘密——零拷贝技术

这是Kafka目前实时数据传输管道的标准解决方案,也是Kafka高吞吐的秘密之一,零拷贝。

RocketMQ零拷贝——Mmap

Mmap全称Memory Mapped Files。简单描述其作用就是:将磁盘文件映射到内存,用户通过修改内存就能修改磁盘文件。
它的工作原理是直接利用操作系统的Page来实现文件到物理内存的直接映射,完成映射之后你对物理内存的操作会被同步到磁盘上(操作系统在适当的时候)。

通过mmap也有一个很明显的缺陷——不可靠,写到mmap中的数据并没有被真正地写到磁盘,操作系统会在程序主动调用flush的时候才把数据真正写到磁盘。

RocketMQ主要通过MappedByteBuffer对文件进行读写操作。其中,利用了NIO中的FileChannel模型将磁盘上的物理文件直接映射到用户态的内存地址中(这种Mmap的方式减少了传统IO将磁盘文件数据在操作系统内核地址空间的缓冲区和用户应用程序地址空间的缓冲区之间来回进行拷贝的性能开销),将对文件的操作转化为直接对内存地址进行操作,从而极大地提高了文件的读写效率(正因为需要使用内存映射机制,故RocketMQ的文件存储都使用定长结构来存储,方便一次将整个文件映射至内存)。
如图:

聊聊消息队列高性能的秘密——零拷贝技术

总结

  • CPU比I/O性能好很多,应当尽力给CPU让步,让它去做更多的事情,于是就有了DMA。DMA对CPU说,”你告诉我搬什么数据,搬到哪里,搬好了我告诉你,你先去忙别的”
  • 我们发现,在数据传输过程中,有两次CPU的Copy可以省去,于是就有了内存映射技术(Mmap)、SendFile技术(内核数据Copy),让CPU不需要再白忙活了
  • 市面上熟知的优秀中间件如RocketMQ使用的零拷贝技术是Mmap、Kafka使用的则是SendFile

参考资料:
《极客时间——深入浅出计算机组成原理》
Kafka顺序读写与零拷贝(kafka为什么这么快)

Original: https://www.cnblogs.com/deepSleeping/p/14605644.html
Author: DeepSleeping丶
Title: 聊聊消息队列高性能的秘密——零拷贝技术

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/714808/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • nginx安装配置步骤

    ​ yum install gcc gcc-c++ pcre pcre-devel openssl openssl-devel zlib zlib-devel -y [root@n…

    技术杂谈 2023年7月11日
    094
  • wsl访问windows文件,默认root登录

    在wsl中执行explorer.exe .在command中执行ubuntu1804.exe config –default-user root 本博客是个人工作中记录…

    技术杂谈 2023年6月1日
    0106
  • ETCD分布式存储部署

    一、ETCD 概述 ETCD 是一个分布式一致性k-v存储系统,可用于服务注册发现与共享配置。具有一下优点: 简单: 相比于晦涩难懂的paxos算法,etcd基于相对简单且易实现的…

    技术杂谈 2023年7月10日
    0102
  • ORACLE数据恢复方法(提交事务也可以)

    今天在操作数据库的时候,发现数据操作错误,想要恢复,但是没有用事务,按理说,设置成不默认提交事务,此时所做的各种操作都没有反应到数据库中。这时,你可以rollback事务,撤销所有…

    技术杂谈 2023年5月31日
    096
  • 燕千云AITSM重塑IT服务管理

    IT服务经历了三个阶段,缘起于设备管理,兴起于灾难恢复,发展于IT服务管理。IT服务发展到目前的阶段,企业所使用的系统功能也由孤立的系统转变为综合的集成系统,IT服务所管理的对象也…

    技术杂谈 2023年7月23日
    075
  • 对工作分配问题的求解

    工作分配问题是一个典型的回溯问题,利用回溯思想能很准确地得到问题的解。我们就针对如下一个案例做一个系统的分析: 问题描述 有 (n) 份工作要分配给 (n) 个人来完成,每个人完成…

    技术杂谈 2023年5月31日
    098
  • B站(bilibili) 等级升级脚本-云函数版

    前言 云函数运行会莫名其妙的报错(我也不知道为什么,我这边测试有时候报错,有时候不会),并非代码有错,建议在本地运行。 由于之前写的代码有些bug,后面又又又又又又又更新了。 最后…

    技术杂谈 2023年6月21日
    0100
  • Servlet版本冲突导致页面404

    先准备好了Tomcat环境以及用Idea打了一个Servlet war包想看看效果,结果发现页面跳转一直报404错误,检查了跳转url,项目结构等情况后,问题依旧没有解决。最后偶然…

    技术杂谈 2023年6月21日
    0111
  • flink metric库的使用和自定义metric-reporter

    flink内部实现了一套metric数据收集库。 同时flink自身系统有一些固定的metric数据, 包括系统的一些指标,CPU,内存, IO 或者各个task运行的一些指标。具…

    技术杂谈 2023年6月21日
    095
  • Django同时支持http/https(转载)

    声明著作权:Django同时支持http/https – Alita的文章 – 知乎 https://zhuanlan.zhihu.com/p/385440…

    技术杂谈 2023年7月10日
    0104
  • java实现简易的局域网对话系统

    先说一下 写的确实比较一般,别喷 为什么呢,疫情原因,学校提前两周期末考试,时间也不太充足,将就一下 服务器代码: package xcvcvcx; import java.io….

    技术杂谈 2023年7月24日
    079
  • 【NFC】近距离无线通信概览

    近距离无线通信 (NFC) 是一组近距离无线技术,通常只有在距离不超过 4 厘米时才能启动连接。借助 NFC,您可以在 NFC 标签与 Android 设备之间或者两台 Andro…

    技术杂谈 2023年5月31日
    0127
  • OAuth2.0基本知识

    前置知识 关注客户端开发者的简易性 通过组织在资源拥有者和HTTP服务商之间的被批准的交互动作代表用户 允许第三方应用代表用户获得访问的权限 为Web应用、桌面应用、手机和起居室设…

    技术杂谈 2023年6月21日
    0110
  • 归并排序算法

    java代码: 1 public static void main(String[] args) { 2 int arr[] = {2,7,1,5,9,6,10}; //要排序的数…

    技术杂谈 2023年7月11日
    079
  • 白帽专访丨一个靠肝挖洞的大佬,单家SRC斩获166666元?

    白帽江湖人才辈出,传奇人物不胜枚举,这里只用实力说话,也许你没见过大佬真容,但ta的”传说”或许早有耳闻~ Xrayteam安全团队的xxxeyJ:&#82…

    技术杂谈 2023年5月31日
    094
  • Vue学习笔记(二):Vue实例与指令

    每一个Vue应用都要通过Vue实例实现,实例化Vue语法格式如下: 接下来,通过一个代码段说明Vue构造器有哪些基本内容: 上述示例中是在创建Vue实例时与div容器进行挂载,这是…

    技术杂谈 2023年7月24日
    095
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球