【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 硬件级,极低延迟

相关推荐
重生之我是Java开发战士2 小时前
【计算机网络】网络层:IP 协议、路由选择与新型网络技术解析
网络·tcp/ip·计算机网络
lllljz2 小时前
blenderGIS出现too large extent错误
java·服务器·前端
女王大人万岁2 小时前
Go标准库 path 详解
服务器·开发语言·后端·golang
方便面不加香菜2 小时前
Linux基础开发工具--yum和vim
linux·运维·服务器
酣大智2 小时前
计算机网络概述
运维·网络
小马_xiaoen2 小时前
WebSocket与SSE深度对比与实战 Demo
前端·javascript·网络·websocket·网络协议
铁手飞鹰2 小时前
[Linux笔记]内核裁剪
linux·笔记·linux内核裁剪
夏乌_Wx2 小时前
fork、内存管理与虚拟内存总结
linux
上海云盾-小余2 小时前
企业 Web 安全 “零死角”:抗 DDoS + 云 WAF + 安全服务组合方案
网络·安全·ddos