跳至主要內容

零拷贝

大约 3 分钟中间件os

描述零拷贝的底层原理

一、问题背景

如何在磁盘IO成为性能瓶颈时,优化文件传输性能 ?

二、传统文件传输

2.1、传统文件传输的问题

早期的IO操作(传统文件传输),内存与磁盘的数据传输都是由CPU来完成的,而此时CPU不能执行其他任务,会特别浪费CPU。

服务端客户端 文件传输

  1. 4次「用户态」与「内核态」的上下文切换
  2. 4次数据拷贝(2次DMA + 2次CPU拷贝)
    alt text

2.2、可优化点

  1. 减少「用户态与内核态的上下文切换」,即减少 系统调用 次数
  2. 减少「内存拷贝」次数,用户缓冲区 在整个过程中是没有不必要存在的

三、零拷贝

零拷贝-实现方式:

  1. mmap + write
  2. sendfile
  3. SG-DMA + sendfile

3.1、mmap + write

mmap系统调用会直接把内核缓冲区中的数据 映射用户空间,这样 操作系统内核 和 用户空间 就不需要再进行任何的 数据拷贝 操作。

mmap替换read,可减少1次数据拷贝过程。

共需 4次上下文切换 + 3次数据拷贝(2次DMA + 1次CPU拷贝)

alt text
alt text

3.2、sendfile

使用 sendfile 替代 read 和 write 两个系统调用,合并磁盘读取 + 网络发送两个操作,该系统调用可以直接把 内核缓冲区 中的数据拷贝至 Socket缓冲区,而无需拷贝至 用户空间

sendfile 替换 read & write,可减少 2次上下文切换 以及 1次数据拷贝。

共需 2次上下文切换 + 3次数据拷贝(2次DMA拷贝 + 1次CPU拷贝)
alt text

然而以上均不是真正的零拷贝技术。

3.3、真正的零拷贝

网卡支持 SG-DMA技术,可进一步减少通过CPU将 内核缓冲区 中的数据拷贝至 Socket缓冲区 的过程。

共需要 2次上下文切换 + 2次数据拷贝(2次DMA拷贝)
alt text

SG-DMA + sendfile 只需 2次数据拷贝,全程没有通过CPU来搬运数据,所有数据都是通过DMA传输。

注意:零拷贝技术不允许进程对文件内容做进一步加工。

四、零拷贝应用

  1. 消息队列中间件 Kafka
  2. 负载均衡中间件 Nginx

五、参考文献

  1. https://xiaolincoding.com/os/8_network_system/zero_copy.html#_9-1-什么是零拷贝open in new window