Nginx中AIO与page cache本质互斥:AIO必须配合directio绕过页缓存走O_DIRECT路径,仅对≥阈值大文件生效;小文件则依赖sendfile+页缓存。二者不可共存,需按场景择一配置。

Linux 下的 aio(异步 I/O)和文件缓存(page cache)本质上是两条不同路径:aio 绕过 page cache(需 O_DIRECT),而缓存优化依赖 page cache。二者不能共存,配置时必须明确取舍——不是“配合”,而是“选其一”。关键看你的场景:要极致低延迟大文件读?选 aio + directio;要高命中率、小文件快、通用性强?靠 page cache + sendfile。
先搞清 aio 和 page cache 的根本冲突
aio 在 Linux 中真正生效的前提是使用 O_DIRECT 打开文件,这意味着数据不经过内核页缓存,直接与磁盘交互。而 page cache 的核心价值恰恰是把热数据留在内存里,避免反复读盘。所以:
-
aio on;+directio→ 强制绕过 page cache,aio 才可能调用io_submit -
sendfile on;或普通read()→ 重度依赖 page cache,aio 配置被忽略或报错 -
aio on;单独写在 http 块里 → 不触发任何异步行为,nginx 启动可能失败或静默退回到同步 read()
真 AIO 配置(适合视频/ISO 等大文件分发)
仅当满足全部条件时,Nginx 才会走内核原生异步路径(io_submit):
- 内核 ≥ 4.18(推荐 ≥ 5.1),且编译 Nginx 时含
--with-file-aio - 文件系统为 XFS(首选)或 ext4(≥5.8 内核 + DAX 支持)
- 配置必须在
location块内,且与directio成对出现 - 文件大小 ≥
directio设置值(如directio 4m),且按directio_alignment(默认 512B,XFS 建议设为 4k)对齐
示例(安全有效):
location /dl/ {
alias /storage/downloads/;
aio on;
directio 4m;
directio_alignment 4k;
output_buffers 1 128k;
sendfile off;
tcp_nopush on;
}
page cache 路径(适合绝大多数网站、API、小文件)
这才是更通用、更省心、性能也不差的方案。重点不在“禁用缓存”,而在“让缓存更高效”:
- 确保
sendfile on;开启,搭配tcp_nopush on;减少小包 - 调大
vm.vfs_cache_pressure(如设为 50)减缓 dentry/inode 回收,加速路径查找 - 合理设置脏页参数:
vm.dirty_ratio=30、vm.dirty_background_ratio=5,平衡写入吞吐与延迟 - 挂载时加
noatime,nodiratime,避免每次访问都写时间戳 - SSD 存储可加
discard(TRIM),HDD 可设commit=60延长日志刷盘间隔
折中方案:aio threads(兼容性优先)
如果你无法升级内核、文件不对齐、或不想关 sendfile,又希望缓解阻塞,可用线程池模拟异步读:
- Nginx 编译需含
--with-threads - 定义线程池:
thread_pool default threads=32 max_queue=65536; - 配置中写
aio threads;(不是aio on;),它与sendfile不互斥 - 注意:本质仍是同步系统调用 + 多线程调度,有上下文切换开销,不如真 AIO 高效

















