Nginx I/O优化之异步IO与线程池

 

异步I/O


传统:在用户空间发起了read调用,用户空间这个进程就会被阻塞,阻塞之后就开始去读磁盘,将磁盘内容读到磁盘高速缓冲区,然后再读到用户缓冲区。整个这个流程结束再唤醒该用户进程,该用户进程再去做其他操作了。

异步I/O:在调取read的时候,用户进程可以处理其他任务,不会阻塞。

#在开启异步I/O的时候可以设定线程池
Syntax: aio on | off | threads[=pool];
Default: aio off;
Context: http, server, location

Syntax: aio_write on | off;
Default: aio_write off;
Context: http, server, location

 

aio


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

This directive appeared in version 0.8.11.

Enables or disables the use of asynchronous file I/O (AIO) on FreeBSD and Linux:

location /video/ {
    aio            on;
    output_buffers 1 64k;
}

On FreeBSD, AIO can be used starting from FreeBSD 4.3. Prior to FreeBSD 11.0, AIO can either be linked statically into a kernel:

options VFS_AIO

or loaded dynamically as a kernel loadable module:

kldload aio

On Linux, AIO can be used starting from kernel version 2.6.22. Also, it is necessary to enable directio, or otherwise reading will be blocking:

location /video/ {
    aio            on;
    directio       512;
    output_buffers 1 128k;
}

On Linux, directio can only be used for reading blocks that are aligned on 512-byte boundaries (or 4K for XFS). File’s unaligned end is read in blocking mode. The same holds true for byte range requests and for FLV requests not from the beginning of a file: reading of unaligned data at the beginning and end of a file will be blocking.

When both AIO and sendfile are enabled on Linux, AIO is used for files that are larger than or equal to the size specified in the directio directive, while sendfile is used for files of smaller sizes or when directio is disabled.

location /video/ {
    sendfile       on;
    aio            on;
    directio       8m;
}

Finally, files can be read and sent using multi-threading (1.7.11), without blocking a worker process:

location /video/ {
    sendfile       on;
    aio            threads;
}

Read and send file operations are offloaded to threads of the specified pool. If the pool name is omitted, the pool with the name “default” is used. The pool name can also be set with variables:

aio threads=pool$disk;

By default, multi-threading is disabled, it should be enabled with the --with-threads configuration parameter. Currently, multi-threading is compatible only with the epollkqueue, and eventport methods. Multi-threaded sending of files is only supported on Linux.

 

 

线程池 


使用需要编译添加--with-threads,这样就可以采用多线程方式了。正常情况下任务是在worker进程里面执行的,但是对于某些任务的执行可能造成进程阻塞。为了避免这种情况派生出一堆线程去处理该任务

Nginx官方的模块都是非阻塞的,为什么会出现阻塞?这是因为nginx用来做静态资源处理了太多的文件,这些文件特别多,阻塞了。(在nginx使用反向代理的时候,对反向代理的内容可以做磁盘缓存,在处理静态资源的时候会有一个问题,当整个内存不足以缓存所有内容的时候,像sendfile这样的调用或者aio会退化成阻塞的磁盘调用。所以在这里有一个线程池来处理)

线程池的使用场景是用在做静态资源服务读取文件。

[root@www nginx-1.17.9]# ./configure --help | grep thread
  --with-threads                     enable thread pool support

异步I/O允许进程进行不受阻塞或不需要等待I/O完成的I/O操作。aio命令可在Nginx配置的http,server和location区块下使用。 根据在指令所在区块,该指令将为匹配的请求执行异步I/O。 该参数适用于Linux内核2.6.22+和FreeBSD 4.3。 如下代码:

location /data {
     aio on;
}

默认情况下,该参数设置为off。 在Linux上,aio需要启用direction,而在FreeBSD上,sendfile需要禁用以使aio生效。
该指令具有特殊的线程值,可以为发送和读操作启用多线程。 多线程支持仅在Linux平台上可用,并且只能与处理请求的epoll,kqueue或eventport方法一起使用。
为了使用线程值,在编译Nginx时使用–with-threads选项配置多线程支持。 在NGINX全局上下文中使用thread_pool指令添加一个线程池。 在aio配置中使用该线程池:

# in the 'main' context
thread_pool one threads=128 max_queue=0;
thread_pool two threads=32;
 
http {
    server {
        location /one {
            aio threads=one;
        }
 
        location /two {
            aio threads=two;
        }
 
    }

}

 

 

总结


  1. 异步io,aio

    • 在发生io阻塞的时候,让其去处理其他任务
    • aio on|off threads=[pool],server模块中配置
    • nginx的worker进程发生io阻塞以后,把阻塞io的任务放入到一个新的队列中,利用线程去处理这些阻塞io的任务,完成后返回给nginx
    • 定义线程池

      • thread_pool name threads=number [max_queue=number]; 在main中定义
      • 默认配置thread_pool default threads=32 max_queue=65535;
      • aio on threads=default; 使用线程
    • 需要nginx有threads和file-aio模块
    • sendfile和直接io是互斥的,两个不能同时存在
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值