Zero-Copy&sendfile浅析
一、典型IO调用的问题
一个典型的web服务器传送静态文件(如CSS,JS,图片等)的过程如下:
read(file, tmp_buf, len);
write(socket, tmp_buf, len);
首先调用read将文件从磁盘读取到tmp_buf,然后调用write将tmp_buf写入到socket,在这过程中会出现四次数据copy,过程如图1所示

图1

1。当调用read系统调用时,通过DMA(Direct Memory Access)将数据copy到内核模式
2。然后由CPU控制将内核模式数据copy到用户模式下的 buffer中
3。read调用完成后,write调用首先将用户模式下 buffer中的数据copy到内核模式下的socket buffer中
4。最后通过DMA copy将内核模式下的socket buffer中的数据copy到网卡设备中传送。
从上面的过程可以看出,数据白白从内核模式到用户模式走了一 圈,浪费了两次copy,而这两次copy都是CPU copy,即占用CPU资源。
二、Zero-Copy&Sendfile()
Linux 2.1版本内核引入了sendfile函数,用于将文件通过socket传送。
sendfile(socket, file, len);
该函数通过一次系统调用完成了文件的传送,减少了原来 read/write方式的模式切换。此外更是减少了数据的copy,sendfile的详细过程图2所示:


图2
通过sendfile传送文件只需要一次系统调用,当调用 sendfile时:
1。首先通过DMA copy将数据从磁盘读取到kernel buffer中
2。然后通过CPU copy将数据从kernel buffer copy到sokcet buffer中
3。最终通过DMA copy将socket buffer中数据copy到网卡buffer中发送
sendfile与read/write方式相比,少了 一次模式切换一次CPU copy。但是从上述过程中也可以发现从kernel buffer中将数据copy到socket buffer是没必要的。
为此,Linux2.4内核对sendfile做了改进,如图3所示


图3
改进后的处理过程如下:
1。DMA copy将磁盘数据copy到kernel buffer中
2。向socket buffer中追加当前要发送的数据在kernel buffer中的位置和偏移量
3。DMA gather copy根据socket buffer中的位置和偏移量直接将kernel buffer中的数据copy到网卡上。
经过上述过程,数据只经过了2次copy就从磁盘传送出去了。
(可能有人要纠结“不是说Zero-Copy么?怎么还有两次copy啊”,事实上这个Zero copy是针对内核来讲的,数据在内核模式下是Zero-copy的。话说回来,文件本身在瓷盘上要真是完全Zero-copy就能传送,那才见鬼了 呢)。
当前许多高性能http server都引入了sendfile机制,如nginx,lighttpd等。
三、Java NIO中的transferTo()
Java NIO中
FileChannel.transferTo(long position, long count, WriteableByteChannel target)
方法将当前通道中的数据传送到目标通道target中,在支持Zero-Copy的linux系统中,transferTo()的实现依赖于sendfile()调用。
四、参考文档
《Zero Copy I: User-Mode Perspective》http://www.linuxjournal.com/article/6345?page=0,0
《Efficient data transfer through zero copy》http://www.ibm.com/developerworks/linux/library/j-zerocopy
《The C10K problem》http://www.kegel.com/c10k.html
http://blog.csdn.net/u013074465/article/details/45822431
Zero-Copy&sendfile浅析的更多相关文章
- Linux -- 如何减少IO过程中的CPU copy
四种I/O方式的对比 1. Buffered I/O read(file, tmp_buf, len); write(socket, tmp_buf, len); 上下文切换:4次 CPU copy: ...
- Linux-磁盘及网络IO工作方式解析
PIO与DMA 有必要简单地说说慢速I/O设备和内存之间的数据传输方式. PIO我们拿磁盘来说,很早以前,磁盘和内存之间的数据传输是需要CPU控制的,也就是说如果我们读取磁盘文件到内存中,数据要经过C ...
- 网络IO和磁盘IO详解
1. 缓存IO 缓存I/O又被称作标准I/O,大多数文件系统的默认I/O操作都是缓存I/O.在Linux的缓存I/O机制中,数据先从磁盘复制到内核空间的缓冲区,然后从内核空间缓冲区复制到应用程序的地址 ...
- Zero-Copy技术
概述 考虑这样一种常用的情形:你需要将静态内容(类似图片.文件)展示给用户.那么这个情形就意味着你需要先将静态内容从磁盘中拷贝出来放到一个内存buf中,然后将这个buf通过socket传输给用户,进而 ...
- 什么是Zero-Copy?
概述 考虑这样一种常用的情形:你需要将静态内容(类似图片.文件)展示给用户.那么这个情形就意味着你需要先将静态内容从磁盘中拷贝出来放到一个内存buf中,然后将这个buf通过socket传输给用户,进而 ...
- 【转载】什么是Zero-Copy
转载:https://blog.csdn.net/u013256816/article/details/52589524 概述 考虑这样一种常用的情形:你需要将静态内容(类似图片.文件)展示给用户.那 ...
- linux socket编程示例
#include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include &l ...
- 零拷贝Zero copy-linux and java
背景-几种拷贝方式 方式1:Copying in Two Sample System Calls read(file, tmp_buf, len); write(socket, tmp_buf, le ...
- Java I/O体系从原理到应用,这一篇全说清楚了
本文介绍操作系统I/O工作原理,Java I/O设计,基本使用,开源项目中实现高性能I/O常见方法和实现,彻底搞懂高性能I/O之道 基础概念 在介绍I/O原理之前,先重温几个基础概念: (1) 操作系 ...
随机推荐
- Java基础知识总结
写代码: 1,明确需求.我要做什么? 2,分析思路.我要怎么做?1,2,3. 3,确定步骤.每一个思路部分用到哪些语句,方法,和对象. 4,代码实现.用具体的java语言代码把思路体现出来. 学习新技 ...
- ThinkPHP常用配置路径
//系统常量定义 //去THinkPHP手册中进行查找 echo "<br>"."网站的根目录地址".__ROOT__." "; ...
- Java 数组基础
数组 数组(Array):相同类型数据的集合. 定义数组 方式1(推荐,更能表明数组类型) type[] 变量名 = new type[数组中元素的个数]; 比如: int[] a = new int ...
- Win10 UWP 开发学习代码(不断更新)
页面之间跳转(传值) string txt = "Spring Lee"; this.Frame.Navigate(typeof(BlankPage1),txt); 另一个页面接收 ...
- vi command
进入vi的命令 vi filename :打开或新建文件,并将光标置于第一行首 vi +n filename :打开文件,并将光标置于第n行首 vi + filename :打开文件,并将光标置于最后 ...
- Mybatis使用总结
一.最基本的配置文件 <?xml version="1.0" encoding="UTF-8" ?><!DOCTYPE configurati ...
- itertools
0. Python中引入itertools 1. 笛卡尔积: product(iter1, iter2,...,iterN,[repeat=i]) from itertools import prod ...
- gdb调试常用实用命令和core dump文件的生成
1.生成core dump文件的方法: $ ulimit -c //查看是否为0 如果为0 $ ulimit -c unlimited 这样在程序崩溃以后会在当前目录生成一个core.xxx ...
- ECharts学习(2)--饼状图之南丁格尔图
1.上一篇中讲了如何绘制一个简单的柱状图,这次要画的是饼图,饼图主要是通过扇形的弧度表现不同类目的数据在总和中的占比,它的数据格式比柱状图更简单,只有一维的数值,不需要给类目.因为不在直角坐标系上,所 ...
- Hadoop---Google MapReduce(转)
1. MapReduce是干啥的 因为没找到谷歌的示意图,所以我想借用一张Hadoop项目的结构图来说明下MapReduce所处的位置,如下图. Hadoop实际上就是谷歌三宝的开源实现,Hadoop ...