0
点赞
收藏
分享

微信扫一扫

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

我是小小懒 2022-08-17 阅读 53


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:

​http​​​, ​​server​​​, ​​location​

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 ​​epoll​​​, ​​kqueue​​​, and ​​eventport​​ methods. Multi-threaded sending of files is only supported on Linux.

 

 

线程池 

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

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

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

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

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

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

异步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是互斥的,两个不能同时存在
举报

相关推荐

0 条评论