Nginx sendfile配置

Nginx开启sendfile配置来提高文件的传输速率
例如:

http {
...
  sendfile on
...
}

大多数sendfile配置开启后,Nginx在进行数据传输,会调用sendfile()函数, Linux 2.0+ 以后的推出的一个系统调用。对比一般的数据的网络传输sendfile会有更少的切换和更少的数据拷贝。
情况一,linux的正常IO:

read(file, tmp_buf, len);
write(socket, tmp_buf, len);

此种情况下数据的传输经过了
两个函数调用实际上经过以下的一些底层步骤
1,系统调用read函数产生一次切换,user mode→kernel mode 将数据通过DMA拷贝至kernel buffer。
2,kernel buffer利用DMA数据拷贝至user buffer,write函数返回,此时又产生一次上下文切换,kernel mode→user mode。
3,系统调用write函数,又产生一次上下文切换user mode →kernel mode,用DMA方式,将数据从user buffer拷贝至kernel socket buffer。
4,write函数返回,又产生一次上下文切换,kernel mode →user mode将数据从kernel socket buffer拷贝至协议栈。
总的来说数据发生了四次拷贝,产生了四次上下文切换。
磁盘→kernel buffer→user buffer→kernel socket buffer→存储协议

情况二,调用sendfile函数:
sendfile(socket, file, len);
磁盘→kernel buffer→kernel socket buffer→协议栈
产生一次系统调用,两次上下文切换,三次数据拷贝。
步骤减少了,切换减少了,拷贝减少了,自然性能就提升了。

什么是DAM?
DMA(Direct Memory Acess)是一种不通过CPU,直接在系统内存和外设之间交互数据的接口技术。正常来说如果使用CPU来进行数据交换,则需要首先使用CPU读取外设字节至内部寄存器,然后再将寄存器中的字节写入内存。而DMA的出现则可以直接将外设字节一次写入内存,加快了数据写入内存的速度。

下面讲一讲sendfile的相关配置
tcp_nopush和tcp_nodelay
1,tcp_nopush = on 会设置调用tcp_cork方法,这个也是默认的,结果就是数据包不会马上传送出去,等到数据包最大时,一次性的传输出去,这样有助于解决网络堵塞。
2,tcp_nodelay会尽量发送小数据块,而不是等一定数据量满了之后才发送。
3,当使用sendfile函数时,tcp_nopush才起作用,它和指令tcp_nodelay是互斥的

参考:
https://blog.csdn.net/hairetz/article/details/6549306

你可能感兴趣的:(Nginx sendfile配置)