零拷贝
零拷贝是一种避免CPU在内存中复制数据的优化技术,通过减少数据复制次数,显著提升I/O性能。
零拷贝核心优势:
减少CPU拷贝次数:数据不经过用户空间
降低内存带宽占用:避免多次数据复制
减小上下文切换:减少用户态/内核态切换
降低延迟:缩短数据处理路径
传统拷贝
1. 从硬盘读取文件数据 → 内核缓冲区(第1次拷贝)
2. 内核缓冲区 → 用户缓冲区(第2次拷贝)
3. 用户缓冲区 → 目标文件内核缓冲区(第3次拷贝)
4. 目标内核缓冲区 → 硬盘(第4次拷贝)
零拷贝
1. 硬盘文件 → 内核缓冲区(仅此1次拷贝)
2. 内核缓冲区直接 → 目标文件(系统自动完成)
图解
传统拷贝:
[硬盘] → 拷贝1 → [内核缓冲区] → 拷贝2 → [用户缓冲区] → 拷贝3 → [目标内核缓冲区] → 拷贝4 → [目标硬盘]
零拷贝:
[硬盘] → 单次拷贝 → [内核缓冲区]
↳ 内核直接传输 → [目标硬盘]
零拷贝技术的三种实现方式
系统调用级零拷贝:
如
io.Copy()
内部使用的sendfile()
系统调用无需用户代码调整,Go标准库自动使用
当满足以下两个条件时,
io.Copy()
会尝试使用零拷贝机制(以Linux为例):src
是*os.File
类型(或其他实现了io.ReaderFrom
接口的类型)dst
是net.TCPConn
类型(或其他实现了io.WriterTo
接口的类型)
内存映射文件:
syscall.Mmap()
将文件直接映射到内存程序像访问数组一样访问文件
管道接力传输:
使用
io.Pipe()
连接处理过程数据在内存中直接传递,不经磁盘
最后更新于