nginx中配置sendfile及详细说明

配置示例

http {
    # other directives
    sendfile    on;
    # other directives
}

指令说明

语法: sendfile on | off;
默认值: sendfile off;
上下文: http,server,location,if in location

指定是否使用sendfile系统调用来传输文件。
sendfile系统调用在两个文件描述符之间直接传递数据(完全在内核中操作),从而避免了数据在内核缓冲区和用户缓冲区之间的拷贝,操作效率很高,被称之为零拷贝。

原理解释

read/write

在传统的文件传输方式(read、write/send方式),具体流程细节如下:

  1. 调用read函数,文件数据拷贝到内核缓冲区
  2. read函数返回,数据从内核缓冲区拷贝到用户缓冲区
  3. 调用write/send函数,将数据从用户缓冲区拷贝到内核socket缓冲区
  4. 数据从内核socket缓冲区拷贝到协议引擎中

在这个过程当中,文件数据实际上是经过了四次拷贝操作:
硬盘—>内核缓冲区—>用户缓冲区—>内核socket缓冲区—>协议引擎

sendfile

sendfile系统调用则提供了一种减少拷贝次数,提升文件传输性能的方法。

  1. sendfile系统调用利用DMA引擎将文件数据拷贝到内核缓冲区,之后数据被拷贝到内核socket缓冲区中
  2. DMA引擎将数据从内核socket缓冲区拷贝到协议引擎中

这里没有用户态和内核态之间的切换,也没有内核缓冲区和用户缓冲区之间的拷贝,大大提升了传输性能。
这个过程数据经历的拷贝操作如下:
硬盘—>内核缓冲区—>内核socket缓冲区—>协议引擎

带有DMA收集拷贝功能的sendfile

对于带有DMA收集拷贝功能的sendfile系统调用,还可以再减少一次内核缓冲区之间的拷贝。具体流程如下:

  1. sendfile系统调用利用DMA引擎将文件数据拷贝到内核缓冲区,之后,将带有文件位置和长度信息的缓冲区描述符添加到内核socket缓冲区中
  2. DMA引擎会将数据直接从内核缓冲区拷贝到协议引擎中

这个过程数据经历的拷贝操作如下:
硬盘—>内核缓冲区—>协议引擎

参考资料

1、Linux 中直接 I/O 机制的介绍
2、Linux 中的零拷贝技术,第 1 部分
3、Linux 中的零拷贝技术,第 2 部分

推荐阅读更多精彩内容

  • 什么是零拷贝 维基上是这么描述零拷贝的:零拷贝描述的是CPU不执行拷贝数据从一个存储区域到另一个存储区域的任务,这...
    tomas家的小拨浪鼓阅读 9,144评论 12 47
  • 本文探讨Linux中主要的几种零拷贝技术以及零拷贝技术适用的场景。为了迅速建立起零拷贝的概念,我们拿一个常用的场景...
    卡巴拉的树阅读 41,220评论 13 83
  • 目录 [TOC] 简介 零拷贝(zero-copy)技术可以减少数据拷贝和共享总线操作的次数,消除通信数据在存储器...
    无相菩提阅读 799评论 0 2
  • 天朗气清一色秋, 万里枫叶笑枝头。 千千落木无情下, 人若有情晚风收。 取尽青山做画屏, 舀干黄河洗心情。 摘得明...
    望舍阅读 89评论 2 7
  • 习惯了的事情,不易改变。晚饭过后都会再买简单的食物来做夜宵,今天忘了。 九点半下楼,有点凉,依然闪烁着霓虹灯,红的...
    稳儿阅读 40评论 0 1