Zero-Copy

2019-05-14  本文已影响0人  packet

服务器将硬盘上的文件,传给用户,需要几次拷贝?
解决这个问题,需要明白具体的工作流程是什么?

read(file, buf, len);        // 把文件读到缓冲区buf中
write(socket, buf, len);  // 把buf中的内容发送给用户

关于哪个步骤需要拷贝:

  1. 把磁盘中文件拷贝到kernel buf
  2. 把kernel buf拷贝到user buf
  3. 把user buf拷贝到socket 中的kernel buf
  4. 把socket buffer 拷贝到 网卡设备的buffer
    其实1,2是read,3,4是write
    所以说,一共拷贝4次,而且kernel mod和user mod的切换也是4次。

Linux 2.1内核开始引入了sendfile函数。省去了将操作系统的read buffer拷贝到程序的buffer,以及从程序buffer拷贝到socket buffer的步骤
而是直接将kernel buf 拷贝 到 socket buf。 实际上是把2,3两部步骤整合了。


拷贝次数
上下文切换

这里把上下文的切换次数从4次减少到2次,同时也把数据copy的次数从4次降低到了3次。
Java NIO中的FileChannal.transferTo()方法就是这样的实现,这个实现是依赖于操作系统底层的sendFile()实现的
但是,这还不是Zero-Copy。

  1. 将文件拷贝到kernel buffer中
  2. 向socket buf中写入当前要拷贝数据的位置和偏移量
  3. 根据socket buf中的位置和偏移量,直接将kernel buf拷贝到网卡buffer中。


这样只需要拷贝两次。这里的零拷贝是针对kernel来讲的,数据在kernel模式下是Zero-Copy。

在kafka和netty中会使用到Zero-Copy,大大提升了性能。

感谢:什么是Zero-Copy?

上一篇下一篇

猜你喜欢

热点阅读