零拷贝和应用

1.什么是零拷贝

零拷贝是指计算机在执行IO操作的时候, CPU不需要将数据从一个存储区复制到另一个存储区, 进而减少上下文切换以及 CPU 拷贝的时间, 这是一种IO操作优化技术

零拷贝不是没有拷贝数据, 而是减少用户态, 内核态的切换次数 和 CPU拷贝次数

2. 传统IO

3. 实现方式

3.1.mmap + write

虚拟内存把内核空间和用户空间的虚拟地址映射到同一个物理地址, 从而减少数据拷贝次数, mmap技术就是利用了虚拟内存的这个特点, 它将内核中的读缓冲区与用户空间的缓冲区进行映射, 所有的IO操作都在内核中完成

  1. 用户进程通过mmap方法向操作系统内核发起 IO 调用,上下文从用户态切换为内核态。

  2. CPU 利用DMA控制器,把数据从硬盘中拷贝到内核缓冲区。

  3. 上下文从内核态切换回用户态,mmap 方法返回。

  4. 用户进程通过write 方法向操作系统内核发起IO 调用,上下文从用户态切换为内核态。

  5. CPU 将内核缓冲区的数据拷贝到的 socket 缓冲区。

  6. CPU 利用DMA 控制器,把数据从 socket 缓冲区拷贝到网卡,上下文从内核态切换回用户态,write 调用返回。

mmap+write 实现的零拷贝,I/O 发生了4次用户空间与内核空间的上下文切 换,以及3 次数据拷贝(包括了2次DMA拷贝和1 次CPU 拷贝)。

3.2 sendfile

sendfile 表示在两个文件描述符之间传输数据,它是在操作系统内核中操作的, 避免了数据从内核缓冲区和用户缓冲区之间的拷贝操作

  1. 用户进程发起·sendfile 系统调用,上下文(切换 1)从用户态转向内核态

  2. DMA控制器,把数据从硬盘中拷贝到内核缓冲区。

  3. CPU 将读缓冲区中数据拷贝到 socket 缓冲区

  4. DMA 控制器,异步把数据从 socket 缓冲区拷贝到网卡,

  5. 上下文(切换2)从内核态切换回用户态,sendfile 调用返回。

2次上下文切换,2次DMA拷贝,一次cpu 拷贝

3.3 带DMA收集功能sendfile (sendfile+DMA Scatter/Gather)

linux 2.4版本之后,对sendfile做了优化升级,引入SG-DMA技术,其实就是对DMA拷贝加入了scatter/gather操作,它可以直接从内核空间缓冲区中将数据读取到网卡。使用这个特点搞零拷贝,即还可以多省去一次CPU拷贝

  1. 用户进程发起sendfile系统调用,上下文(切换1)从用户态转向内核态

  2. DMA控制器,把数据从硬盘中拷贝到内核缓冲区。

  3. CPU把内核缓冲区中的文件描述符信息(包括内核缓冲区的内存地址和偏移量)发送到socket缓冲区

  4. DMA控制器根据文件描述符信息,直接把数据从内核缓冲区拷贝到网卡

  5. 上下文(切换2)从内核态切换回用户态sendfile调用返回。

可以发现,sendfile+DMA scatter/gather实现的零拷贝,I/O发生了2次用户空间与内核空间的上下文切换,以及2次数据拷贝。其中2次数据拷贝都是包DMA拷贝。这就是真正的 零拷贝(Zero-copy) 技术,全程都没有通过CPU来搬运数据,所有的数据都是通过DMA来进行传输的。

4. DMA 技术说明

DMA,英文全称是Direct Memory Access,即直接内存访问。DMA本质上是一块主板上独立的芯片,允许外设设备和内存存储器之间直接进行IO数据传输,其过程不需要CPU的参与

5.应用场景

RocketMQKafka都使用到了零拷贝的技术。

对于MQ而言,无非就是生产者发送数据到MQ然后持久化到磁盘,之后消费者从MQ读取数据。

对于RocketMQ来说这两个步骤使用的是mmap+write,而Kafka则是使用mmap+write持久化数据,发送数据使用sendfile

6.java对零拷贝支持

6.1 Java NIOmmap的支持

MappedByteBuffer

6.2 Java NIOsendfile的支持

FileChanneltransferTo()/transferFrom(),底层就是sendfile() 系统调用函数

 
posted @   蚂蚁吃豆腐  阅读(111)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?
点击右上角即可分享
微信分享提示