directio 并非简单开启即生效,必须满足四前提:location 使用 root/alias、文件≥阈值、文件系统支持 direct i/o、内核与 nginx 编译支持;且需禁用 sendfile 和 gzip,补全 content-length 头,才能绕过 page cache 实现内存可控、cpu 降低、延迟稳定。

直接启用 directio 并不能自动提升大文件 IO 效率,它真正起效的前提是:明确绕过内核 Page Cache 的必要性,并在 Nginx 静态服务场景中严格满足触发条件与协同配置。
为什么大文件必须绕开 Page Cache
当 Nginx 用默认方式分发一个 4GB 的视频或 ISO 镜像时,内核会将整块数据逐步加载进 Page Cache。这会导致:
- 瞬时占用数 GB 物理内存,挤占其他进程或系统缓存空间
- 触发 kswapd 内存回收,引发 CPU 尖峰和 I/O 延迟抖动
- 多个并发下载时,Page Cache 中大量冷数据反复换入换出,实际读盘反而变慢
- 在低配云主机或容器环境中,极易触发 OOM Killer 杀掉 worker 进程
directio 在 Nginx 中的生效条件
该机制仅对静态文件服务有效,且需同时满足以下四点:
- 配置在使用
root或alias指向磁盘路径的location块中;proxy_pass不触发 directio - 文件大小 ≥ 设定阈值(如
directio 1m),小文件仍走常规路径 - 目标文件位于支持 direct I/O 的文件系统(ext4/xfs),挂载参数不能含
barrier=0或data=writeback - 操作系统支持
O_DIRECT(Linux 2.4.10+),且 Nginx 编译未禁用--without-directio
关键配置与协同要点
单独写 directio 1m 不够,必须关闭冲突机制并补全响应头:
-
directio 1m;—— 设置触发阈值,设为off则完全禁用 -
sendfile off;—— sendfile 依赖 page cache,二者互斥 -
gzip off;—— 压缩需在用户态完成,与 directio 冲突 -
add_header Content-Length $sent_http_content_length;—— 若后端未返回该头,Nginx 需自行计算,否则 fallback 到普通读取
它带来的真实收益是什么
directio 的核心价值不是“绝对更快”,而是更稳、更可控、更省内存:
- 降低内存带宽压力:跳过 page cache,避免 GB 级文件反复装入/挤出内存,防止 cache thrashing
- 减少 CPU 开销:省去页缓存管理、脏页回写、LRU 维护等内核路径,实测在 10Gbps 场景下 CPU 降低 8–15%
- 规避延迟毛刺:避免因页回收抖动导致的读取延迟飙升或连接超时,尤其适合长连接、高并发下载










