sendfile与linux内核native aio互斥:前者依赖page cache实现零拷贝发送,后者通过directio绕过cache仅负责异步读取,二者路径冲突、目标不同,无法共存。

不能。sendfile 与 Linux 内核本地 AIO(即基于 io_submit/io_getevents 的 native AIO)互斥,无法配合使用,更谈不上“激活物理盘读取极限”。
这是由二者底层机制根本冲突决定的:
sendfile() 依赖 page cache
它在内核态直接将数据从文件页缓存(page cache)复制到 socket 缓冲区,全程不经过用户空间,也不触发磁盘直读。它追求的是零拷贝 + 高吞吐,但前提是数据已在内存中。native AIO(aio on + directio)绕过 page cache
必须用O_DIRECT打开文件,数据从磁盘直达用户 buffer,完全跳过内核页缓存。它的价值在于规避 cache 污染、控制大文件随机读延迟、适配自管理缓存系统——但它不提供网络发送能力,只负责“把磁盘数据读进指定内存”。
二者目标不同、路径冲突:一个要 cache,一个禁 cache;一个读+发一体化,一个只读不发。Linux 内核不允许同一路径同时启用。
常见误配(必然失效):
-
aio on; sendfile on;—— Nginx 启动时会静默禁用 AIO 或报错 “aio is not supported” -
directio 4m; sendfile on;—— directio 已强制绕过 page cache,sendfile 失去数据源,直接退化为普通 read + write
真正释放物理盘读取极限的组合是:
-
AIO 读 + 独立线程池处理 + lock-free 输出缓冲:如视频分片场景,用
aio on; directio 4m; sendfile off;,读完交由线程池解码/封装,再通过writev()或sendmsg()发送 -
sendfile 单独启用(小/热文件):对 ≤1MB 的静态资源(JS/CSS/图标),
sendfile on; directio off;反而更高效——靠 page cache 命中 + 零拷贝,避免 AIO 调度开销 -
混合策略(按文件大小自动分流):Nginx 允许在不同 location 或 if 判断中分别配置,例如:
/static/ → sendfile on
/video/ → aio on; directio 4m; sendfile off
若目标是压测物理盘极限,还需确认:
- 文件系统为 XFS(推荐)或 ext4(≥5.8,开启 DAX 更佳)
- 内核 ≥5.1,编译含
--with-file-aio,且/proc/sys/fs/aio-nr未逼近aio-max-nr - 磁盘为 NVMe,I/O 调度器设为
none或mq-deadline,队列深度 ≥256 - 用
iostat -x 1观察aqu-sz(平均请求队列长度),持续 >32 表示底层已饱和,需扩容或调优
不复杂但容易忽略。











