linux aio 线程,nginx的线程池和I/O机制

nginx的线程池和I/O机制

启用对线程的支持

./configure --prefix=/home/jackie/software/nginx \

--with-openssl=/home/jackie/Downloads/nginx/openssl-1.0.2g \

--with-pcre=/home/jackie/Downloads/nginx/pcre-8.38 \

--with-zlib=/home/jackie/Downloads/nginx/zlib-1.2.8 \

--with-http_ssl_module \

--with-threads \

--with-debug

make -j4

make install

配置说明

定义线程池

thread_pool mypool threads=32 max_queue=65536;

thread_pool

Syntax: thread_pool name threads=number [max_queue=number];

Default:

thread_pool default threads=32 max_queue=65536;

Context: main

nginx提供了一个名为default的默认线程池,线程数量为32,队列中操作数量的上限为65536.

在AIO中使用线程池

location ~ /downloads/ {

aio threads=mypool;

directio 8k;

output_buffers 1 128k;

sendfile on;

}

aio

Syntax: aio on | off | threads[=pool];

Default:

aio off;

Context: http, server, location

使用使用指令aio threads,则使用默认的线程池default。

directio

Syntax: directio size | off;

Default:

directio off;

Context: http, server, location

directio_alignment

Syntax: directio_alignment size;

Default:

directio_alignment 512;

Context: http, server, location

sendfile

Syntax: sendfile on | off;

Default:

sendfile off;

Context: http, server, location, if in location

sendfile_max_chunk

Syntax: sendfile_max_chunk size;

Default:

sendfile_max_chunk 0;

Context: http, server, location

延伸阅读资料

nginx的aio和sendfile

启用aio时会自动启用directio,小于directio定义的大小的文件则采用sendfile进行发送,超过或等于directio定义的大小的文件,将采用aio线程池进行发送,也就是说aio和directio适合大文件下载。因为大文件不适合进入操作系统的buffers/cache,这样会浪费内存,而且Linux AIO(异步磁盘IO)也要求使用directio的形式。

sendfile_max_chunk可以减少阻塞调用sendfile()所花费的最长时间。因为Nginx不会尝试一次将整个文件发送出去,而是每次发送大小为256KB的块数据。

注意,Nginx从1.7.11开始为AIO引入了线程池支持,能够使用多线程读取和发送文件,以免工人进程被阻塞。要启用多线程支持,configure时需要显式加入–with-threads选项。

nginx对Linux native AIO机制的应用(配置篇)

要使aio生效需把directio设置为打开状况,并且如果aio生效,那么将自动不使用sendfile(),这在linux下这是显然的,要么利用aio读到缓存区,要么利用sendfile()直接发送出去,两者不可兼用。

这种设计貌似刚好把linux下aio和sendfile两种机制的优点很好的结合起来使用。对于大文件采用aio,节省cpu,而对于小文件,采用sendfile,减少拷贝;并且对于大文件aio采用directio,避免挤占文件系统缓存,让文件系统缓存更多的小文件。

从理论上来看,这种配置比较适合系统内存有限、小文件请求比较多、间隔有几个大文件请求的Web环境;如果内存足够大,那么应该充分利用文件系统缓存,而directio使得aio无法使用缓存是衡量最终是否需要采用aio的一个需要仔细考虑的因素

关于aio

关于sendfile

高性能Tomcat:漫谈行走在sendfile之上的Tomcat

Tomcat中的NIO模式和APR模式对静态文件处理的高效根源在于地从对不同的系统调用,和普通的文件传输不同的是NIO和APR方式都使用的操作系统的sendfile系统调用来对文件进行IO,而普通的方式是使用了read和write系统调用。那么这两种类型有什么不同呢,这是本文的关键点:

使用read和write方式的时候,将文件输出到网络的流程是这样的:

1,read操作先将线程从用户态切换到内核态,将文件从磁盘读到内核缓冲器。

2,read将文件从内核缓冲区读到用户地址空间,同时线程从内核态切换到用户态。

3,read返回。

4,对文件进行处理

5,write将线程从用户态切换到内核态,将文件写到操作系统内核网络部分的缓冲区。

6,write将线程切换到用户态并返回。

上面的的过程涉及到四次操作系统内核态与用户态的切换,代价是昂贵的。由于事实上我们并不需要对静态文件进行处理这个步骤,为什么要绕一个圈子呢从内核copy到用户态又copy到内核态呢,因此sendfile来了。

我们再来看看sendfile的处理流程:

1,将文件读到操作系统的内核缓冲区。

2,将文件copy到操作系统跟网络相关的内核缓冲区。

上面不会涉及到内核态到用户态以及用户态到内核态的切换,sendfile是linux2+version提供的系统调用,而且在linux2.4+version版本之后提供能zero-copy特性,上面这些说明了sendfile为我们的程序提高了问静态文件处理的能力和性能。

关于nginx的threadpool

NGINX引入线程池 性能提升9倍

实际上,最幸运的情况是,读取和发送文件操作不去处理缓慢的硬盘驱动器。如果我们有足够多的内存来存储数据集,那么操作系统将会足够聪明地在被称作“页面缓存”的地方,缓存频繁使用的文件。

“页面缓存”的效果很好,可以让NGINX在几乎所有常见的用例中展示优异的性能。从页面缓存中读取比较快,没有人会说这种操作是“阻塞”。而另一方面,卸载任务到一个线程池是有一定开销的。

因此,如果内存有合理的大小并且待处理的数据集不是很大的话,那么无需使用线程池,NGINX已经工作在最优化的方式下。

卸载读操作到线程池是一种适用于非常特殊任务的技术。只有当经常请求的内容的大小,不适合操作系统的虚拟机缓存时,这种技术才是最有用的。至于可能适用的场景,比如,基于NGINX的高负载流媒体服务器。这正是我们已经模拟的基准测试的场景。

我们如果可以改进卸载读操作到线程池,将会非常有意义。我们只需要知道所需的文件数据是否在内存中,只有不在内存中时,读操作才应该卸载到一个单独的线程中。

有意思的个人站点

若非注明,均为原创,欢迎转载,转载请注明来源:nginx的线程池和I/O机制

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值