Linux splice零拷贝技术原理






传统read/write文件操作需要数据在内核空间和用户空间之间传递,相当于数据存在副本,而splice通过在内核内部直接传递数据页的指针实现零拷贝,根本就不需要用户空间参与传递。
1. 运行环境
以Linux kernel-4.9.0来说明(Debian 9发行版使用)
· 一台装有Debian 9 发行版的实机
· 编译Linux kernel-4.9.0的源代码
· 内核测试模块(参考上一篇匿名管道)
· 用户空间测试程序(如图二~图三所示)
· qemu-system-x86_64虚拟机能运行编译源代码后的内核
2. 底层原理
(2.1) 匿名管道作为媒介:
· splice使用匿名管道作为数据传输的媒介
· 数据从一个文件描述符被拼接到匿名管道,再从匿名管道拼接到另一个文件描述符
(2.2) 页面重映射:
· 页面缓存(page cache):文件数据通常缓存在内核的页面缓存中
· 内核通过重映射内存页面的方式移动数据(实际数据不需要物理移动,只是修改页表项)
当数据从文件splice到匿名管道时,内核实际上是将文件在页面缓存中的页面直接链接到匿名管道的缓冲区中,而不是复制数据。
3. 使用场景
特别是在需要处理大量数据传输的场景中,但是至少有一个文件描述符必须是匿名管道
· 文件到文件的拷贝
· 网络套接字之间的数据传输
· 文件到网络套接字的传输
· 任何支持splice操作的文件描述符之间 的数据传输
4. 测试splice
(4.1) qemu运行编译Linux kernel-4.9.0源码的系统,匿名管道页面的查看(内核测试模块)可参考上一篇关于匿名管道的介绍,用户空间可执行程序在系统中的路径(如图四所示)。
(4.2) 运行用户空间测试程序,可以看到输出文件内容和输入文件内容一致(如图五所示)。