directio是nginx绕过内核页缓存、直接读写磁盘的i/o优化机制,适用于≥阈值的大静态文件(如视频、镜像),需配合sendfile off、gzip off及content-length头使用,可降低内存带宽、cpu及i/o调度开销。

directio 不是用来“提速”的,而是让 Nginx 在服务超大文件(如 >1GB 的视频、ISO、归档包)时更稳、更可控、更省内存。它绕过内核 page cache,避免缓存污染、内存抖动和连接超时,特别适合 CDN 边缘节点、下载站、镜像分发等场景。
为什么超大文件必须绕开 page cache
默认 buffered I/O 会把整个大文件逐步加载进页缓存,带来连锁问题:
- 单次下载一个 5GB 文件,可能瞬间吃掉数 GB 物理内存,挤占其他服务资源
- 触发内核 kswapd 回收,引发 CPU 尖峰与 I/O 阻塞
- 多个并发下载时,page cache 中大量冷数据反复换入换出,实际读盘反而变慢
- 在低配云主机或容器中,极易触发 OOM Killer 杀掉 nginx worker 进程
directio 生效的硬性前提
配置了 directio 却没效果?大概率是底层没对齐或不支持:
- 文件系统需支持 direct I/O:XFS 原生稳定;ext4 需内核 ≥5.8 + 挂载参数 dioread_nolock 或启用 DAX
- Nginx 必须编译含 --with-file-aio(主流发行版已默认开启)
- 配置中 aio on 和 directio N 必须成对出现,N 建议设为 4m(即 ≥4MB 才启用 directio)
- 读取偏移与长度需按设备逻辑块对齐(通常 4KB),Nginx 在 sendfile + directio 组合下会自动对齐,无需手动干预
典型安全高效配置示例
适用于 /media/archive/ 下的冷数据归档服务:
location ^~ /media/archive/ {
alias /storage/archive/;
sendfile on;
directio 4m;
aio on;
aio_write off;
output_buffers 1 256k;
open_file_cache off;
tcp_nopush on;
}
- sendfile on:仍启用零拷贝网络传输,aio 只增强其底层磁盘读环节
- directio 4m:仅 ≥4MB 文件走 O_DIRECT,小文件继续用 page cache,兼顾热资源效率
- open_file_cache off:防止缓存海量大文件句柄导致 fd 耗尽
- output_buffers 1 256k:减少用户态缓冲区拷贝次数,适配 DMA 直传粒度
常见误用坑点
很多性能问题不是没开 directio,而是开错了:
- 在 SSD/NVMe 上对小文件(
- 同时配置 sendfile on 和 aio threads 是无效组合,二者逻辑冲突
- 未关闭 open_file_cache 却服务海量大文件,会导致 inode 缓存膨胀、stat 系统调用暴涨
- 误以为 directio 能“调预读”,其实它完全跳过内核 readahead —— 优化重点应放在块设备调度器(如 NVMe 设 noop)和全局预读窗口(blockdev --setra 8192)上










