零拷贝技术
零拷贝技术是linux下避免在内核态和用户态之间来回拷贝数据的技术。
零拷贝技术在系统层面有两种实现方式,一个是面向socket(网络数据的拷贝),一个面向文件系统(文件间的数据拷贝)。
¶零拷贝的优点
- 减少cpu拷贝
- 减少内存带宽占用
- 减少用户空间和内核空间之间的上下文切换
¶
¶零拷贝与多路复用(NIO)
事件驱动模型是多路复用IO使用的编程范式
多路复用IO的高效是由零拷贝技术实现的,需要传输的数据使用零拷贝技术被更快的拷贝到socket上,通过多路复用IO建立的网络通信进行传输
¶零拷贝原理
linux上零拷贝主要是减少数据的额外拷贝次数以及避免在内核态和用户态之间切换,因为普通状态下数据拷贝需要在内核态和用户态之间切换,不仅会增加数据拷贝次数,还会因为空间切换耗费额外性能。
¶用户态与核心态
linux系统分为两个空间,用户空间和内核空间。内核空间主要驻留系统进程,用户空间驻留用户进程。用户进程要切换进内核态需要调用系统调用。
Linux的用户态和内核态
¶操作系统层面的零拷贝
¶sendfile
在两个文件描述符之间拷贝数据,面向socket网络传输的零拷贝系统调用,只适用于将数据从文件拷贝到socket上。
¶原理解析
¶函数解析
1 |
|
¶实际运用
¶mmap
面向文件系统拷贝数据的系统调用
用于申请内存空间,这个内存空间可以作为进程间通信的共享内存,拷贝文件时可以将文件映射到共享内存,不用在内核空间与用户空间之间切换。
¶原理解析
¶函数解析
1 |
|
¶实际运用
¶splice
适用于两个文件描述符之间移动数据,splice利用linux的管道缓冲机制,需要一个文件描述符是表示管道设备。
¶原理解析
¶函数解析
1 | /* See feature_test_macros(7) */ |
¶实际运用
¶tee
linux种的管道命令,适用于管道描述符之间数据传输。
¶原理解析
¶实际运用
¶零拷贝技术的应用
jvm层面的零拷贝
libevent的零拷贝
netty的零拷贝
kafka的零拷贝
mq的零拷贝
redis的零拷贝
¶参考文献
- Linux 中的零拷贝技术,第 1 部分
- 漫谈Java IO之 Netty与NIO服务器
- 深入理解Linux, NIO和Netty中的零拷贝(Zero-Copy)
- Netty常见面试题总结
- Related articles
- Java NIO(一)select 和 epoll底层实现原理
- Select、poll、Epoll、KQueue区别
- Netty零拷贝之CompositeByteBuf实际用法
- Netty专栏 ( 三)——— Netty的ByteBuf
- Netty-内存池化
- 彻底理解Netty
- netty内存分配总览
- Netty中的装饰者模式
- 操作系统层面聊聊BIO,NIO和AIO (epoll)
- linux网络编程:splice函数和tee( )函数高效的零拷贝
- sendfile man
- mmap man
- splice man