目录
  1. 1. 零拷贝技术
    1. 1.1. 零拷贝的优点
    2. 1.2.
    3. 1.3. 零拷贝与多路复用(NIO)
    4. 1.4. 零拷贝原理
      1. 1.4.1. 用户态与核心态
    5. 1.5. 操作系统层面的零拷贝
      1. 1.5.1. sendfile
        1. 1.5.1.1. 原理解析
        2. 1.5.1.2. 函数解析
        3. 1.5.1.3. 实际运用
      2. 1.5.2. mmap
        1. 1.5.2.1. 原理解析
        2. 1.5.2.2. 函数解析
        3. 1.5.2.3. 实际运用
      3. 1.5.3. splice
        1. 1.5.3.1. 原理解析
        2. 1.5.3.2. 函数解析
        3. 1.5.3.3. 实际运用
      4. 1.5.4. tee
        1. 1.5.4.1. 原理解析
        2. 1.5.4.2. 实际运用
    6. 1.6. 零拷贝技术的应用
    7. 1.7. 参考文献
零拷贝技术

零拷贝技术

零拷贝技术是linux下避免在内核态和用户态之间来回拷贝数据的技术。
零拷贝技术在系统层面有两种实现方式,一个是面向socket(网络数据的拷贝),一个面向文件系统(文件间的数据拷贝)。

零拷贝的优点

  • 减少cpu拷贝
  • 减少内存带宽占用
  • 减少用户空间和内核空间之间的上下文切换

零拷贝与多路复用(NIO)

事件驱动模型是多路复用IO使用的编程范式
多路复用IO的高效是由零拷贝技术实现的,需要传输的数据使用零拷贝技术被更快的拷贝到socket上,通过多路复用IO建立的网络通信进行传输

零拷贝原理

linux上零拷贝主要是减少数据的额外拷贝次数以及避免在内核态和用户态之间切换,因为普通状态下数据拷贝需要在内核态和用户态之间切换,不仅会增加数据拷贝次数,还会因为空间切换耗费额外性能。

用户态与核心态

linux系统分为两个空间,用户空间和内核空间。内核空间主要驻留系统进程,用户空间驻留用户进程。用户进程要切换进内核态需要调用系统调用。
Linux的用户态和内核态

操作系统层面的零拷贝

sendfile

在两个文件描述符之间拷贝数据,面向socket网络传输的零拷贝系统调用,只适用于将数据从文件拷贝到socket上。

原理解析

函数解析

1
2
3
#include <sys/sendfile.h>
ssize_t sendfile (int __out_fd, int __in_fd, off_t *__offset, size_t __count) __THROW;
ssize_t sendfile64 (int __out_fd, int __in_fd, __off64_t *__offset, size_t __count) __THROW;

实际运用

mmap

面向文件系统拷贝数据的系统调用
用于申请内存空间,这个内存空间可以作为进程间通信的共享内存,拷贝文件时可以将文件映射到共享内存,不用在内核空间与用户空间之间切换。

原理解析

函数解析

1
2
3
#include <sys/mman.h>
void *mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset);
int munmap(void *addr, size_t length);

实际运用

splice

适用于两个文件描述符之间移动数据,splice利用linux的管道缓冲机制,需要一个文件描述符是表示管道设备。

原理解析

函数解析

1
2
3
4
/* See feature_test_macros(7) */
#define _GNU_SOURCE
#include <fcntl.h>
ssize_t splice(int fd_in, loff_t *off_in, int fd_out, loff_t *off_out, size_t len, unsigned int flags);

实际运用

tee

linux种的管道命令,适用于管道描述符之间数据传输。

原理解析

实际运用

零拷贝技术的应用

jvm层面的零拷贝
libevent的零拷贝
netty的零拷贝
kafka的零拷贝
mq的零拷贝
redis的零拷贝

参考文献

  1. Linux 中的零拷贝技术,第 1 部分
  2. 漫谈Java IO之 Netty与NIO服务器
  3. 深入理解Linux, NIO和Netty中的零拷贝(Zero-Copy)
  4. Netty常见面试题总结
  5. Related articles
  6. Java NIO(一)select 和 epoll底层实现原理
  7. Select、poll、Epoll、KQueue区别
  8. Netty零拷贝之CompositeByteBuf实际用法
  9. Netty专栏 ( 三)——— Netty的ByteBuf
  10. Netty-内存池化
  11. 彻底理解Netty
  12. netty内存分配总览
  13. Netty中的装饰者模式
  14. 操作系统层面聊聊BIO,NIO和AIO (epoll)
  15. linux网络编程:splice函数和tee( )函数高效的零拷贝
  16. sendfile man
  17. mmap man
  18. splice man
文章作者: rack-leen
文章链接: http://yoursite.com/2020/06/26/Linux/Linux%E8%BF%90%E7%94%A8%E6%8A%80%E6%9C%AF/%E9%9B%B6%E6%8B%B7%E8%B4%9D%E6%8A%80%E6%9C%AF/
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 rack-leen's blog
打赏
  • 微信
  • 支付宝

评论