什么是零拷贝
零拷贝(Zero-Copy)就是一种避免 CPU 将数据从一块存储拷贝到另外一块存储的技术,是指将数据直接从磁盘文件复制到网卡设备中,而不需要经由应用程序之手。
零拷贝的好处
避免操作系统内核缓冲区之间进行数据拷贝操作
避免操作系统内核和用户应用程序地址空间这两者之间进行数据拷贝操作
用户应用程序可以避开操作系统直接访问硬件存储
避免不必要的系统调用和上下文切换
数据传输尽量让 DMA 来做,需要拷贝的数据可以先被缓存起来,对数据进行处理尽量让硬件来做
Linux中零拷贝实现
Linux 中零拷贝技术实现方式通常有 2 种:
mmap() + write()
sendfile()
零拷贝的实现原理
mmap() + write():
mmap() 系统调用函数会直接把内核缓冲区里的数据映射到用户空间,这样,操作系统内核与用户空间就不需要再进行任何的数据拷贝操作。具体过程:
应用进程调用了 mmap() 后,DMA 会把磁盘的数据拷贝到内核的缓冲区里,接着应用进程跟操作系统内核共享这个缓冲区
应用进程再调用 write(),操作系统直接将内核缓冲区的数据拷贝到 socket 缓冲区中,这一切都发生在内核态,由 CPU 来搬运数据
最后,把内核的 socket 缓冲区里的数据,拷贝到网卡的缓冲区里,这个过程是由 DMA 搬运的
sendfile():
在 Linux 内核版本 2.1 中,提供了一个专门发送文件的系统调用 sendfile()。具体过程:
发起 sendfile() 系统调用,操作系统由用户态空间切换到内核态空间
通过 DMA 引擎将数据从磁盘拷贝到内核态空间的输入的 socket 缓冲区中
将数据从内核空间拷贝到与之关联的 socket 缓冲区
将 socket 缓冲区的数据拷贝到协议引擎中
sendfile() 系统调用结束,操作系统由用户态空间切换到内核态空间