文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

Java Nio,Netty,Kafka 中经常提到“零拷贝”到底是什么?

2024-11-28 14:57

关注

1 I/O 中断原理

在 DMA 技术出现之前,应用程序与磁盘之间的 I/O 操作都是通过 CPU 的中断完成的。

图片图片

可以看到,整个数据的传输过程,都要需要 CPU 亲自参与搬运数据的过程,而且这个过程,CPU 是不能做其他事情的。

假如通过千兆网卡或者磁盘传输大量数据时,使用 CPU 来拷贝的话,对 CPU 资源是种极大的消耗。

2 DMA 方式

DMA 的全称是直接内存访问(Direct Memory Access),是一种硬件设备绕开 CPU 独立直接访问内存的机制。

目前支持 DMA 的硬件包括:网卡、声卡、显卡、磁盘控制器等。

图片图片

基于 DMA 访问方式,系统主内存于硬盘或网卡之间的数据传输可以绕开 CPU 的全程调度,数据搬运的工作交给 DMA 控制器,在传输过程中,CPU 可以继续处理其他的工作,提升系统的资源利用率。

图片图片

3 传统 I/O 方式

为了理解零拷贝技术的思路,首先了解一下传统 I/O 方式存在的问题。

Linux 系统中,传统的访问方式是通过 write() 和 read() 两个系统调用实现的,通过 read()  函数读取文件到到缓存区中,然后通过 write() 方法把缓存中的数据输出到网络端口 。

图片图片

下图分别对应传统 I/O 操作的数据读写流程,整个过程涉及 4 次上下文切换、 2 次 CPU 拷贝、2 次 DMA 拷贝总共 4 次拷贝

图片图片

因为发生了两次系统调用,一次是 read() ,一次是 write(),用户程序向内核发起系统调用时,CPU 将用户进程从用户态切换到内核态;当系统调用返回时,CPU 将用户进程从内核态切换回用户态。

综上,想要提升文件传输的性能,因此我们需要减少「上下文切换」和「数据拷贝」的次数。

3 零拷贝方式

零拷贝技术实现的方式通常有 2 种:mmap + write 、sendfile、sendfile + DMA scatter-gather 。

3.1 mmap + write

mmap 是 Linux 提供的一种内存映射文件的机制,它实现了将内核中读缓冲区地址与用户空间缓冲区地址进行映射,从而实现内核缓冲区与用户缓冲区的共享。

图片图片

基于 mmap + write 系统调用的零拷贝方式,整个拷贝过程会发生 4 次上下文切换,1 次 CPU 拷贝和 2 次 DMA 拷贝。

图片图片

用户程序读写数据的流程如下:

mmap 的拷贝虽然减少了 1 次 CPU 拷贝,提升了效率,但也存在一些隐藏的问题。

当 mmap 一个文件时,如果这个文件被另一个进程所截获,那么 write 系统调用会因为访问非法地址被 SIGBUS 信号终止,SIGBUS 默认会杀死进程并产生一个 coredump,服务器可能因此被终止。

3.2 sendfile

sendfile 系统调用在 Linux 内核版本 2.1 中被引入,目的是简化通过网络在两个通道之间进行的数据传输过程。

通过 sendfile 系统调用,数据可以直接在内核空间内部进行 I/O 传输,从而省去了数据在用户空间和内核空间之间的来回拷贝。

sendfile 系统调用的引入,不仅减少了 CPU 拷贝的次数,还减少了上下文切换的次数,它的伪代码如下:

图片图片

基于 sendfile 系统调用的零拷贝方式,整个拷贝过程会发生 2 次上下文切换,1 次 CPU 拷贝和 2 次 DMA 拷贝。

图片图片

用户程序读写数据的流程如下:

相比较于 mmap 内存映射的方式,sendfile 少了 2 次上下文切换,但是仍然有 1 次 CPU 拷贝操作。

3.3 sendfile + DMA gather copy

Linux 2.4 版本的内核对 sendfile 系统调用进行修改,为 DMA 拷贝引入了 gather 操作。

它将内核空间的读缓冲区中对应的数据描述信息(内存地址、地址偏移量)记录到相应的网络缓冲区中,由 DMA 根据内存地址、地址偏移量将数据批量地从读缓冲区拷贝到网卡设备中,这样就省去了内核空间中仅剩的 1 次 CPU 拷贝操作。

图片图片

在硬件的支持下,sendfile 拷贝方式不再从内核缓冲区的数据拷贝到 socket 缓冲区,取而代之的仅仅是缓冲区文件描述符和数据长度的拷贝,这样 DMA 引擎直接利用 gather 操作将页缓存中数据打包发送到网络中即可,本质就是和虚拟内存映射的思路类似。

图片图片

基于 sendfile + DMA gather copy 系统调用的零拷贝方式,整个拷贝过程会发生 2 次上下文切换、0 次 CPU 拷贝以及 2 次 DMA 拷贝,用户程序读写数据的流程如下:

5 写到最后

无论是传统 I/O 拷贝方式还是引入零拷贝的方式,2 次 DMA 拷贝是都少不了的,因为两次 DMA 都是依赖硬件完成的。

拷贝方式

CPU拷贝

DMA拷贝

系统调用

上下文切换

传统方式(read + write)

2

2

read / write

4

内存映射(mmap + write)

1

2

mmap / write

4

sendfile

1

2

sendfile

2

sendfile + DMA gather copy

0

2

sendfile

2

RocketMQ 选择了 mmap + write 这种零拷贝方式,适用于业务级消息这种小块文件的数据持久化和传输;

而 Kafka 采用的是 sendfile 这种零拷贝方式,适用于系统日志消息这种高吞吐量的大块文件的数据持久化和传输。

但是值得注意的一点是,Kafka 的索引文件使用的是 mmap + write 方式,数据文件使用的是 sendfile 方式。

来源:勇哥Java实战内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯