nginx针对下载场景编译优化

在 Nginx 里,directio 不需要额外模块,而 AIO(异步 IO)需要在编译时启用 file AIO

    1. 系统有 AIO 能力
    1. nginx 编译时打开 --with-file-aio

1.底层原理

普通IO:
磁盘 → 内核缓存 → nginx → socket

sendfile:
磁盘 → 内核缓存 → socket

directio:
磁盘 → socket(绕过缓存)

aio:
读磁盘时不阻塞 worker

aio 是减少 worker 阻塞,directio 是减少 page cache 污染,两者常一起用在大文件下载


2.nginx编译系统依赖

Linux 下 aio 依赖 libaio:

2.1Ubuntu / Debian

1
apt install libaio-dev

2.2RHEL / Rocky / CentOS

1
yum install libaio-devel

验证:

1
ls /usr/include/libaio.h

存在即可。


3.编译 nginx 时启用 AIO

下载源码:

1
2
3
wget https://nginx.org/download/nginx-1.26.0.tar.gz
tar xf nginx-1.26.0.tar.gz
cd nginx-1.26.0

关键参数:

1
2
3
4
5
6
./configure \
--prefix=/usr/local/nginx \
--with-file-aio \
--with-threads \
--with-http_ssl_module \
--with-http_v2_module

关键点:

--with-file-aio   # 开启 aio
--with-threads    # 建议开启线程IO

然后:

1
2
make -j$(nproc)
make install

4.确认是否编译成功

1
nginx -V

应看到:

--with-file-aio

5.nginx 配置启用 aio + directio

1
2
3
4
5
6
7
8
9
location /download/ {
root /data/files;

sendfile on;
aio on;
directio 8m; # >8m文件走directio

output_buffers 1 512k;
}

6.directio 的真实限制

directio 不是万能:

1)文件系统要支持 O_DIRECT

支持:

  • ext4
  • xfs

不太行:

  • overlayfs
  • 部分网络存储

2)小文件不会走 directio

directio 8m;

表示:

文件 < 8MB → 普通IO
文件 ≥ 8MB → directio

因为 directio 对小文件反而慢。


7.aio on vs aio threads

现代推荐:

1
aio threads;

比内核 aio 更稳定。

完整推荐:

1
2
3
sendfile on;
aio threads;
directio 8m;

8.生产推荐

高并发下载的真实优化优先级:

CDN > sendfile > aio > directio > worker数量

80% 场景只开 sendfile 就够了,aio/directio 是大文件分发优化