【linux】零拷贝技术

简单来说,"零拷贝"(Zero-copy)并不是指数据真的物理上一次都不拷贝,而是指消除在内核态(Kernel Space)与用户态(User Space)之间冗余的数据拷贝,以及减少 CPU 参与拷贝的工作。

在传统的 I/O 操作中,数据往往要在内核缓冲区和用户缓冲区之间跳来跳去,这不仅浪费内存带宽,还让 CPU 忙于搬砖。

为了让你看清这些"骚操作",我们先看传统的 I/O 流程,再逐一拆解零拷贝的各种实现。


1. 传统 I/O 的痛点(Baseline)

传统的 read + write 操作流程如下:

  1. DMA 拷贝:磁盘 -> 内核缓冲区(Page Cache)。
  2. CPU 拷贝:内核缓冲区 -> 用户缓冲区(应用程序内存)。
  3. CPU 拷贝:用户缓冲区 -> Socket 缓冲区。
  4. DMA 拷贝:Socket 缓冲区 -> 网卡(NIC)。

代价: 4 次上下文切换(User/Kernel 切换),4 次数据拷贝(其中 2 次 CPU 亲自下场)。


2. 零拷贝技术全家桶

① mmap + write(内存映射)

这是最早期的改进方案。既然用户空间和内核空间来回拷贝麻烦,那就直接把内核缓冲区映射到用户空间。

  • 原理 :使用 mmap() 系统调用,让用户进程的虚拟地址指向内核空间的 Page Cache 地址。
  • 过程
  1. DMA 拷贝:磁盘 -> 内核缓冲区。
  2. 内核与用户共享:不需要 CPU 拷贝到用户空间。
  3. CPU 拷贝:内核缓冲区 -> Socket 缓冲区。
  4. DMA 拷贝:Socket 缓冲区 -> 网卡。
  • 优点:减少了 1 次 CPU 拷贝。
  • 缺点 :依然有 4 次上下文切换,且在大并发下可能触发 SIGBUS 错误(如果文件被另一个进程截断)。

② sendfile

Linux 2.1 版本引入,这是真正意义上迈向"零"的一大步。

  • 原理:在一个系统调用内完成数据传输,不再经过用户空间。
  • 过程
  1. DMA 拷贝:磁盘 -> 内核缓冲区。
  2. CPU 拷贝:内核缓冲区 -> Socket 缓冲区。
  3. DMA 拷贝:Socket 缓冲区 -> 网卡。
  • 优点:2 次上下文切换(因为是一个接口 少了mmap结束返回用户态,和再调用write进入内核态过程),3 次拷贝(1 次 CPU 拷贝)。

③ sendfile + DMA Gather Copy(真正的零 CPU 拷贝)

这是 sendfile 的增强版,需要网卡硬件支持。

  • 原理:内核不再把数据拷贝到 Socket 缓冲区,而是只把数据的**内存地址和长度(描述符)**拷贝过去。网卡的 DMA 控制器直接根据这些描述符从内核缓冲区抓取数据。
  • 过程
  1. DMA 拷贝:磁盘 -> 内核缓冲区。
  2. 描述符拷贝:内核将位置信息传给 Socket 缓冲区(极小开销)。
  3. DMA 收集拷贝:网卡直接从内核缓冲区读数据。
  • 优点 :2 次上下文切换,2 次拷贝(0 次 CPU 拷贝)。

④ splice

Linux 2.6.17 引入,它不像 sendfile 只能发文件到 Socket,它更通用。

  • 原理:利用"管道(Pipe)"机制。它在两个文件描述符之间移动数据,而不经过用户空间。
  • 特点:要求传输的两个描述符中至少有一个必须是管道。
  • 效果:实现了内核空间的"原生"数据流转,避免了 CPU 拷贝。

⑤ Direct I/O(直接 I/O)

严格来说,这叫"绕过缓存",也是零拷贝的一种思路。

  • 原理:应用程序直接访问磁盘,跳过操作系统的 Page Cache(内核缓冲区)。
  • 适用场景:数据库(如 MySQL/Oracle)。它们通常有自己的缓存管理机制,不希望 OS 帮倒忙。
  • 缺点:如果数据不在 App 的缓存里,每次都要读磁盘,性能反而可能下降。

⑥ MSG_ZEROCOPY

Linux 4.14 以后引入的高级特性,主要针对 Socket 发送。

  • 原理:利用写时复制(Copy-on-Write)技术。应用层发送数据时,内核不拷贝数据,而是修改页表引用。
  • 适用场景:超大数据包发送(通常 > 10KB 才有收益,否则页表维护开销可能盖过拷贝开销)。

⑦ RDMA(Remote Direct Memory Access)

这是"终极方案",属于硬件级别的零拷贝。

  • 原理:通过特定的网卡,让一台机器可以直接读写另一台机器的内存,完全绕过双方的 CPU 和操作系统内核。
  • 适用场景:高性能计算(HPC)、分布式存储(如 NVMe-over-Fabrics)。

3. 技术对比总结

技术方案 CPU 拷贝次数 上下文切换 关键优势
传统 I/O 2 4 兼容性最强
mmap 1 4 适合多进程共享读取
sendfile 1 2 简单高效,静态资源分发首选
DMA Gather 0 2 目前主流的高性能方案
splice 0 2 灵活,适合代理服务器
RDMA 0 0 硬件级,极低延迟

相关推荐
66清小风1 天前
服务器安装操作系统报X or window manager startup failed, falling back to mode
linux·kylin
西西学代码1 天前
Flutter---路由与导航
服务器·前端·javascript
wangqiaowq1 天前
llama.cpp 启动命令优化
运维·服务器
勇敢牛牛_1 天前
【conreg-client】在Rust中使用向Feign一样的远程调用
网络·rust·feign
double2li1 天前
linux/unix 段错误捕获【续】
linux·运维·服务器·网络·unix
allway21 天前
Linux / Unix last Command Examples
linux·运维·unix
qq_260241231 天前
将盾 CDN:网络网站安全防护体系与实践
网络·安全
dashizhi20151 天前
禁止复制电脑文件、电脑机密数据禁止拷贝、禁止电脑文件复制到U盘和移动硬盘的方法
运维·网络·stm32·安全·电脑
Ralph_Y1 天前
C++网络:一
开发语言·网络·c++
嘿嘿嘿x31 天前
MobaXterm 成功连接 Ubuntu 虚拟机
linux·运维·ubuntu