directio 在 Nginx 处理超大文件时核心优势是更稳、更可控、更省内存,它绕过内核 page cache,避免缓存污染、内存压力及页回收抖动导致的延迟飙升或连接超时。

directio 在 Nginx 处理超大文件(如 >1GB 视频、镜像、归档包)时,核心优势不是“更快”,而是“更稳、更可控、更省内存”——它绕过内核 page cache,避免因缓存污染、内存压力或页回收抖动引发的读取延迟飙升甚至连接超时。
为什么超大文件必须绕开 page cache
当 Nginx 用默认 buffered I/O 服务一个 5GB 的 ISO 文件时,内核会把整块数据逐步加载进 page cache。这会导致:
- 瞬间吃掉数 GB 物理内存,挤占其他服务或系统缓存空间
- 触发内核内存回收(kswapd),造成 CPU 尖峰和 I/O 阻塞
- 多个并发下载时,page cache 中大量冷数据反复换入换出,反而拖慢实际读盘速度
- 在容器或低配云主机上,极易触发 OOM Killer 杀掉 worker 进程
directio + aio 的真实生效条件
directio 不是开关一开就自动加速,它要和底层能力对齐才能真正发挥价值:
- 文件系统需支持 direct I/O:XFS 原生稳定;ext4 需内核 ≥5.8 且挂载时带 dioread_nolock 或使用 dax 模式
- Nginx 编译必须含 --with-file-aio(主流发行版包已默认开启)
- 配置中 aio on 和 directio N 必须成对出现,且 N 建议设为 4m(4MB)或更大,确保只对真正的大文件启用
- 读取偏移与长度需按设备对齐(通常 512B 或 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 直传粒度
别踩这些常见坑
很多性能问题其实源于误用而非没用:
- 在 SSD 或 NVMe 上盲目开启 directio + aio 对小文件(
- 同时配置 sendfile on 和 aio threads 是无效组合,二者逻辑冲突
- 未关闭 open_file_cache 却服务海量大文件,会导致 inode 缓存膨胀、stat 系统调用暴涨
- ext4 文件系统未确认内核版本与挂载参数,直接启用 directio 可能静默退化为同步读


















