写点什么

2023-07-16:讲一讲 Kafka 与 RocketMQ 中零拷贝技术的运用?

  • 2023-07-16
    北京
  • 本文字数:1514 字

    阅读完需:约 5 分钟

2023-07-16:讲一讲 Kafka 与 RocketMQ 中零拷贝技术的运用?


答案 2023-07-16:


什么是零拷贝?


零拷贝(英语: Zero-copy) 技术是指计算机执行操作时,CPU 不需要先将数据从某处内存复制到另一个特定区域。这种技术通常用于通过网络传输文件时节省 CPU 周期和内存带宽。


➢零拷贝技术可以减少数据拷贝和共享总线操作的次数,消除传输数据在存储器之间不必要的中间拷贝次数,从而有效地提高数据传输效率


➢零拷贝技术减少了用户进程地址空间和内核地址空间之间因为上:下文切换而带来的开销


可以看出没有说不需要拷贝,只是说减少冗余[不必要]的拷贝。


下面这些组件、框架中均使用了零拷贝技术:Kafka、Netty、Rocketmq、Nginx、Apache。


传统数据传送机制


比如:读取文件,再用 socket 发送出去,实际经过四次 copy。


伪码实现如下:


buffer = File.read()


Socket.send(buffer)


1、第一次:将磁盘文件,读取到操作系统内核缓冲区;


2、第二次:将内核缓冲区的数据,copy 到应用程序的 buffer;


3、第三步:将 application 应用程序 buffer 中的数据,copy 到 socket 网络发送缓冲区(属于操作系统内核的缓冲区);


4、第四次:将 socket buffer 的数据,copy 到网卡,由网卡进行网络传输。



分析上述的过程,虽然引入 DMA 来接管 CPU 的中断请求,但四次 copy 是存在“不必要的拷贝”的。实际上并不需要第二个和第三个数据副本。应用程序除了缓存数据并将其传输回套接字缓冲区之外什么都不做。相反,数据可以直接从读缓冲区传输到套接字缓冲区。


显然,第二次和第三次数据 copy 其实在这种场景下没有什么帮助反而带来开销(DMA 拷贝速度一般比 CPU 拷贝速度快一个数量级),这也正是零拷贝出现的背景和意义。


打个比喻:200M 的数据,读取文件,再用 socket 发送出去,实际经过四次 copy(2 次 cpu 拷贝每次 100ms ,2 次 DMS 拷贝每次 10ms)


传统网络传输的话:合计耗时将有 220ms


mmap 内存映射(RocketMQ 使用的)


硬盘上文件的位置和应用程序缓冲区(application buffers)进行映射(建立一种一一对应关系),由于 mmap()将文件直接映射到用户空间,所以实际文件读取时根据这个映射关系,直接将文件从硬盘拷贝到用户空间,只进行了一次数据拷贝,不再有文件内容从硬盘拷贝到内核空间的一个缓冲区。


mmap 内存映射将会经历:3 次拷贝: 1 次 cpu copy,2 次 DMA copy;


打个比喻:200M 的数据,读取文件,再用 socket 发送出去,如果是使用 MMAP 实际经过三次 copy(1 次 cpu 拷贝每次 100ms ,2 次 DMS 拷贝每次 10ms)合计只需要 120ms


从数据拷贝的角度上来看,就比传统的网络传输,性能提升了近一倍。



RocketMQ 源码中的 MMAP 运用


RocketMQ 源码中,使用 MappedFile 这个类类进行 MMAP 的映射





Kafka 中的零拷贝


Kafka 两个重要过程都使用了零拷贝技术,且都是操作系统层面的狭义零拷贝,一是 Producer 生产的数据存到 broker,二是 Consumer 从 broker 读取数据。


Producer 生产的数据持久化到 broker,采用 mmap 文件映射,实现顺序的快速写入;


Customer 从 broker 读取数据,采用 sendfile,将磁盘文件读到 OS 内核缓冲区后,直接转到 socket buffer 进行网络发送。


sendfile


linux 2.1 支持的 sendfile


当调用 sendfile()时,DMA 将磁盘数据复制到 kernel buffer,然后将内核中的 kernel buffer 直接拷贝到 socket buffer。在硬件支持的情况下,甚至数据都并不需要被真正复制到 socket 关联的缓冲区内。取而代之的是,只有记录数据位置和长度的描述符被加入到 socket 缓冲区中,DMA 模块将数据直接从内核缓冲区传递给协议引擎,从而消除了遗留的最后一次复制。


一旦数据全都拷贝到 socket buffer,sendfile()系统调用将会 return、代表数据转化的完成。socket buffer 里的数据就能在网络传输了。


sendfile 会经历:3 次拷贝,1 次 CPU copy ,2 次 DMA copy;硬件支持的情况下,则是 2 次拷贝,0 次 CPU copy, 2 次 DMA copy。



发布于: 刚刚阅读数: 4
用户头像

公众号:福大大架构师每日一题 2021-02-15 加入

公众号:福大大架构师每日一题

评论

发布
暂无评论
2023-07-16:讲一讲Kafka与RocketMQ中零拷贝技术的运用?_福大大架构师每日一题_福大大架构师每日一题_InfoQ写作社区