sendfile 在本地 ext4/xfs 文件系统上效果最佳,需启用 sendfile on; 和 tcp_nopush on;,并禁用 gzip、etag、expires 等破坏零拷贝的配置。

sendfile 不是万能开关,它在不同磁盘 I/O 环境下表现差异明显。能否真正发挥零拷贝优势,取决于底层存储特性、文件访问模式和配套配置是否匹配。
本地 ext4/xfs 文件系统:sendfile 效果最佳
这是 sendfile 设计最适配的场景。内核页缓存(page cache)能高效复用热文件,配合 sendfile 实现真正的内核态直传。
- 必须开启 sendfile on;,这是零拷贝路径的起点
- 搭配 tcp_nopush on;,让数据攒满 TCP 段再发,减少中断和小包
- 禁用会破坏零拷贝的模块:gzip off; etag off; expires off;
- 小文件(
NFS/CIFS 等网络文件系统:sendfile 基本失效
多数 NFS 版本(尤其 v3 及以下)和 CIFS 不支持 sendfile 系统调用的底层语义,Nginx 会自动回退到 read+write 模式。
- 即使配置了 sendfile on,strace 也看不到 sendfile() 系统调用
- 实际走的是 4 次拷贝路径:磁盘→内核缓冲区→用户空间→socket 缓冲区→网卡
- 此时优化重点应转向:增大 proxy_buffer_size、启用 open_file_cache、减少 stat() 频次
SSD 与 HDD 的差异:影响不大,但调度策略需区分
sendfile 本身不关心物理介质,但页缓存行为和 I/O 调度器响应不同。
- SSD 随机读快,page cache 命中率高,sendfile 效益更稳定
- HDD 顺序读强、随机读弱,大文件连续读时 sendfile 仍有效,但小文件高频访问易触发磁盘寻道瓶颈
- 建议 HDD 环境额外启用 directio 4m; 和 aio on; 处理 ≥4MB 文件,避免污染 page cache
容器或虚拟化环境:需确认内核与挂载方式
sendfile 在容器中可能受限于内核版本、挂载选项或 cgroup 配置。
- 旧内核(
- 使用 hostPath 或 bind mount 时,若宿主机已启用 sendfile,容器内通常可用
- 使用 overlay2 等联合文件系统时,sendfile 仍生效,但元数据访问(stat)开销略高
- 验证方式:在容器内运行 strace -p $(pgrep nginx) -e trace=sendfile,观察是否持续调用











