您的位置:首页 > 运维架构

Zero Copy(零拷贝)

2016-12-22 19:25 369 查看
转载自:http://blog.csdn.net/fyxxq/article/details/20000045

              http://www.cnblogs.com/metoy/p/4033366.html
       很多Web应用程序都会提供大量的静态内容,其数量多到相当于读完整个磁盘的数据再将同样的数据写回响应套接字(socket)。此动作看似只需较少的 CPU 活动,但它的效率非常低:内核首先从磁盘文件读取数据,然后从内核空间将数据传到用户空间,应用程序又将数据从用户空间返回到内核空间然后传输给socket。实际上,应用程序就相当于是个低效的中间者,从磁盘拿数据放到socket。

       下图展示了数据从文件到socket的内部流程:

        


       每次数据在内核空间和用户空间传输就一次拷贝过程,这是需要占用一定的CPU周期和内存资源的。幸运的是可以通过一个叫zero copy的技术来消除这些拷贝过程。使用了zero copy技术的应用程序的数据传输过程就是内核从磁盘文件读取数据直接传输到socket中,不再经过应用程序这个中间者。zero copy大大改善了应用程序的性能并且减少了用户态和内核态之间的切换次数。

       在linux或者unix系统上,Java类库通过java.nio.channels.FileChannel的transferTo()方法来应用zero copy。可以通过这个方法把一个channel中读取到的字节传输到另一个channel,不再需要数据流经应用程序。

       下图展示了通过transferTo实现数据传输的路径:

        


Java中使用zero copy的数据传输的方法:
public void transferTo(long position,long count,WritableByteChannel target);
       transferTo()方法将数据从一个channel传输到另一个可写的channel上,其内部实现依赖于操作系统对zero copy技术的支持。在unix操作系统和各种linux的发型版本中,这种功能最终是通过sendfile()系统调用实现。

       使用transferTo()方式所经历的步骤:1、transferTo调用会引起DMA将文件内容复制到读缓冲区(内核空间的缓冲区),然后数据从这个缓冲区复制到另一个与socket输出相关的内核缓冲区中。2、第三次数据复制就是DMA把socket关联的缓冲区中的数据复制到协议引擎上发送到网络上。

       这次改善,将数据的复制次数从四次减少到三次(只有一次用到cpu资源)。但这并没有达到零复制的目标。如果底层网络适配器支持收集操作的话,可以进一步减少内核对数据的复制次数。在内核为2.4或者以上版本的linux系统上,socket缓冲区描述符将被用来满足这个需求。这个方式不仅减少了内核用户态间的切换,而且也省去了那次需要cpu参与的复制过程。从用户角度来看依旧是调用transferTo()方法,但是其本质发生了变化:1、调用transferTo方法后数据被DMA从文件复制到了内核的一个缓冲区中。2、数据不再被复制到socket关联的缓冲区中了,仅仅是将一个描述符(包含了数据的位置和长度等信息)追加到socket关联的缓冲区中。DMA直接将内核中的缓冲区中的数据传输给协议引擎,消除了仅剩的一次需要cpu周期的数据复制。如下图:

       


Java nio中提供的FileChannel和SocketChannel实现零拷贝传输数据示例代码:
public long copy(String srcFilename,String destFilename) throws Exception{
File srcFile = new File(srcFilename);
long size = srcFile.length();

FileChannel fileChannel = new FileInputStream(srcFile).getChannel();
FileChannel outChannel = new FileOutputStream(new File(destFilename)).getChannel();
fileChannel.transferTo(0, size, outChannel);

fileChannel.close();
outChannel.close();

return size;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: