Linux-Nginx之sendfile与上下文切换
今天在看nginx thread pool的时候,频繁的看到sendfile,其实以前也经常看到sendfile,只是我平时选择性的忽视而已。。。 先说下sendfile,明天在好好聊下nginx 线程池的一些突发点, 通过伪官方的博客介绍了如何利用nginx 线程池aio,实现9倍的性能…. 个人看了下,他核心的概念就是把你认为堵塞的模块或者说是逻辑扔到线程池里面,然后去接受新的任务,当有结果的时候,在从线程池里面取结果,然后返回。。。 但是如果用在nginx最强大的静态文件处理上,我个人觉得提升不大,毕竟你就算承接了更多的客户端的请求,但是你最后返回数据的逻辑,还是在抢占式的堵塞… 毕竟磁盘io的能力是有限的…. 这只是个人的理解,如有不对的地方,请大家喷下…..
先不扯nginx线程池,回到sendfile…..
现在流行的web服务器里面都提供 sendfile 选项用来提高服务器性能
location /xiaorui.cc/ {
sendfile on;
tcp_nopush on;
aio on;
}
那么sendfile是什么东西,他是怎么影响性能的… … sendfile实际上是 Linux2.0+以后的推出的一个系统调用,web服务器可以通过调整自身的配置来决定是否利用 sendfile这个系统调用。先来看一下不用 sendfile的传统网络传输过程:
read(file,tmp_buf, len);
write(socket,tmp_buf, len);
硬盘 >> kernel buffer >> user buffer>> kernel socket buffer >>协议栈
一个基于socket的服务,首先读硬盘数据,然后写数据到socket 来完成网络传输的。上面2行用代码解释了这一点,不过上面2行简单的代码掩盖了底层的很多操作。来看看底层是怎么执行上面2行代码的:
1、系统调用 read()产生一个上下文切换:从 user mode 切换到 kernel mode,然后 DMA 执行拷贝,把文件数据从硬盘读到一个 kernel buffer 里。
2、数据从 kernel buffer拷贝到 user buffer,然后系统调用 read() 返回,这时又产生一个上下文切换:从kernel mode 切换到 user mode。
3、 系统调用write()产生一个上下文切换:从 user mode切换到 kernel mode,然后把步骤2读到 user buffer的数据拷贝到 kernel buffer(数据第2次拷贝到 kernel buffer),不过这次是个不同的 kernel buffer,这个 buffer和 socket相关联。
4、系统调用 write()返回,产生一个上下文切换:从 kernel mode 切换到 user mode ,然后 DMA 从 kernel buffer拷贝数据到协议栈。
上面4个步骤有4次上下文切换,有4次拷贝,我们发现如果能减少切换次数和拷贝次数将会有效提升性能。在kernel2.0+ 版本中,系统调用 sendfile() 就是用来简化上面步骤提升性能的。sendfile() 不但能减少切换次数而且还能减少拷贝次数。
再来看一下用 sendfile()来进行网络传输的过程:
sendfile(socket,file, len);
硬盘 >> kernel buffer (快速拷贝到kernelsocket buffer) >>协议栈
1、 系统调用sendfile()通过 DMA把硬盘数据拷贝到 kernel buffer,然后数据被 kernel直接拷贝到另外一个与 socket相关的 kernel buffer。这里没有 user mode和 kernel mode之间的切换,在 kernel中直接完成了从一个 buffer到另一个 buffer的拷贝。
2、DMA 把数据从 kernelbuffer 直接拷贝给协议栈,没有切换,也不需要数据从 user mode 拷贝到 kernel mode,因为数据就在 kernel 里。
简单说,sendfile是个比 read 和 write 更高性能的系统接口, 不过需要注意的是,sendfile 是将 in_fd 的内容发送到 out_fd 。而 in_fd 不能是 socket , 也就是只能文件句柄。 所以当 Nginx 是一个静态文件服务器的时候,开启 SENDFILE 配置项能大大提高 Nginx 的性能。 但是当 Nginx 是作为一个反向代理来使用的时候,SENDFILE 则没什么用了,因为 Nginx 是反向代理的时候。 in_fd 就不是文件句柄而是 socket,此时就不符合 sendfile 函数的参数要求了。
Linux-Nginx之sendfile与上下文切换的更多相关文章
- Linux kernel 的 sendfile 是如何提高性能的
Linux kernel 的 sendfile 是如何提高性能的 现在流行的 web 服务器里面都提供 sendfile 选项用来提高服务器性能,那到底 sendfile 是什么,怎么影响性能的呢? ...
- linux+nginx+tomcat负载均衡,实现session同步
linux+nginx+tomcat负载均衡,实现session同步 花了一个上午的时间研究nginx+tomcat的负载均衡测试,集群环境搭建比较顺利,但是session同步的问题折腾了几个小时才搞 ...
- nginx的sendfile指令的作用
linux为了解决对读文件产生的从应用空间到内核空间复制数据产生的效率影响引进了零拷贝.什么是零拷贝?这里就不多说了,请参考http://blog.csdn.net/crazyguang/articl ...
- linux+nginx+mysql+php
LNMP(linux+nginx+mysql+php)服务器环境配置 一.简介 Nginx是俄罗斯人编写的十分轻量级的HTTP服务器,Nginx,它的发音为 “engine X”, 是一个高性能的 ...
- linux独有的sendfile系统调用--“零拷贝,高效”
参考:http://blog.csdn.net/caianye/article/details/7576198 如今几乎每个人都听说过Linux中所谓的"零拷贝"特性,然而我经常碰 ...
- linux nginx配置新项目加域名(设置绑定域名)
转自:linux nginx配置新项目加域名 找到nginx的配置文件 nginx/nginx.conf 第一种方,法直接在nginx.com里面配置 user www www; worker_pro ...
- LNMP(linux+nginx+mysql+php)服务器环境配置【转载】
本文转载自 园友David_Tang的博客,如有侵权请联系本人及时删除,原文地址: http://www.cnblogs.com/mchina/archive/2012/05/17/2507102.h ...
- linux nginx 启动脚本
linux nginx 启动脚本 [root@webtest76 ~]# vi /etc/init.d/nginx #!/bin/bash # nginx Startup script for the ...
- Linux nginx日志按天分割实例
Linux nginx日志按天分割实例 nginx的日志有个小缺点,日志文件一直就是一个,不会自动地进行切割,如果访问量很大的话,将导致日志文件非常大,不便于管理这就需要我们自己来实现了,按日期每 ...
- MacOS + Linux + Nginx
Asp.Net Core 发布和部署( MacOS + Linux + Nginx ) 前言 在上篇文章中,主要介绍了 Dotnet Core Run 命令,这篇文章主要是讲解如何在Linux中,对 ...
随机推荐
- java读取大容量excel之二(空格、空值问题)
最近在项目中发现,对于Excel2007(底层根本是xml) ,使用<java读取大容量excel之一>中的方式读取,若待读取的excel2007文件中某一列是空值,(注意,所谓的空值是什 ...
- [转]dev C++编写windows程序遇到问题
1.工具-编译选项-编译器-在连接器命令行加入以下命令: -mwindows 2.出现错误:undefined reference to `PlaySoundA@12' 解决办法:工具-编译选项-编译 ...
- 文件操作I
<html> <head> <meta charset="utf-8"> </head> <body> <?php ...
- 步步入佳境---UI入门(4) --简单练习
一,创建SingleViewApplication 1,UILabel的简单使用 UILabel *label=[[UILabel alloc]initWithFrame:CGRectMake(0, ...
- 4、SQL基础整理(规范函数)
规范函数: 绝对值 select abs(-5) print abs(-5) 表中取绝对值的方法: select code,name,abs(chinese)as yuwen from xueshen ...
- 关于linux python vim的一些基础知识(很零散)
清空文件夹filenmae下所有文件 rm filename/* vim复制大量代码段 num+yy 从光标起始处复制num个数行 然后 python: 设置中断 1.from IPython imp ...
- 【转】编写更好的CSS代码
原文转自:http://blog.jobbole.com/55067/ 编写好的CSS代码,有助提升页面的渲染速度.本质上,引擎需要解析的CSS规则越少,性能越好.MDN上将CSS选择符归类成四个主要 ...
- eval函数的工作原理
如果您想详细了解eval和JSON请参考以下链接: eval :https://developer.mozilla.org/En/Core_JavaScript_1.5_Reference/Glob ...
- 实现简单ThreadPool
在很多的应用场景,需要根据任务去创建线程去异步处理问题,不过不停的创建线程和销毁线程本身是一个非常耗时和消耗系统资源的事情,所以通常这种情况使用线程池来实现,常用的场景比如web容器对于web请求的处 ...
- markdown简明语法
# markdown简明语法 标签(空格分隔): markdown 本语法只涵盖了常用的内容 [toc] 标题 标题 标题 语法为: 根据需求 可以指定 不同大小的标题 # 顶级 ## 次级 ### ...