Nginx在多磁盘架构下需确保sendfile稳定启用、避免退化为read/write,并按磁盘角色分层配置(SSD用page cache,HDD/RAID用directio+aio),协同调度器(SSD用none,RAID用deadline),强化文件句柄缓存。

在多磁盘(如 RAID 阵列或混合 SSD/HDD)架构下,Nginx 的 sendfile 本身不直接参与磁盘调度决策,但它对底层 I/O 路径的“透明性”决定了能否真正释放多磁盘的并发吞吐能力。优化关键不是调 sendfile 参数本身,而是确保它能稳定启用、不退化,并与硬件特性协同——尤其是绕过无效缓存、适配调度器、隔离冷热路径。
确保 sendfile 始终生效,避免隐式退化
sendfile 只有在纯内核态传输路径畅通时才发挥零拷贝价值。一旦触发用户态干预,就会回退到 read()+write() 模式,不仅失去零拷贝,还会让所有 I/O 请求串行挤在单个 worker 进程的系统调用中,彻底浪费多磁盘并行能力。
- 必须关闭会破坏响应体或头的模块:gzip off; etag off; expires off; sub_filter off;
- 静态资源路径禁用正则匹配(如
location ~* \.(js|css)$),改用前缀匹配(location /static/),避免每次请求都执行 PCRE 解析开销 - 若使用 Nginx Proxy Manager 或自定义 Lua 脚本注入头/重写内容,需确认其是否在 response filter 阶段操作——是则同样禁用 sendfile
按磁盘角色分层调度,避免 page cache 污染
多磁盘环境通常存在性能分层:SSD 承载热静态资源(CSS/JS/小图),RAID10 或 HDD 存放大文件(视频、安装包)。统一用 page cache 缓存所有文件会导致 SSD 上的热数据被大文件驱逐,反而降低整体命中率。
- 对 SSD 上的小文件(≤ 2MB):保持默认行为 ——
sendfile on; tcp_nopush on;,完全依赖内核 page cache + 零拷贝 - 对 RAID/HDD 上的大文件(≥ 4MB):在对应 location 中显式启用直读:
directio 4m; aio on;,跳过 page cache,由内核异步发往磁盘驱动,避免脏页回写和内存争抢 - 不要跨设备混用
directio和普通 sendfile;不同磁盘路径应配置独立 location 块,物理隔离 I/O 模式
协同 Linux I/O 调度器,匹配硬件特性
Nginx 不管理磁盘队列,但它的 I/O 模式(如是否绕过缓存、是否批量提交)直接影响底层调度器的负载特征。SSD 和 RAID 对调度策略敏感度不同:
- SSD 设备(包括 NVMe)建议使用
noop或none调度器:无机械寻道,简单 FIFO 最高效;执行echo none > /sys/block/nvme0n1/queue/scheduler - RAID 阵列(尤其 RAID5/6)建议用
deadline:保障大块顺序读的响应延迟,防止小 IO 饥饿;可通过echo deadline > /sys/block/md0/queue/scheduler临时切换 - 避免在多磁盘系统中全局统一调度策略;应按设备名分别设置,例如 SSD 用
none,RAID 卷用deadline
强化元数据与句柄缓存,减少跨磁盘 stat 开销
当静态资源分布在多个挂载点(如 /ssd/static 和 /raid/downloads),高频请求下反复 stat() 会引发跨设备元数据查找,成为瓶颈。
- 启用细粒度 open_file_cache:在 http 块中配置
open_file_cache max=32000 inactive=60s;,并为不同 location 设置独立缓存键(通过open_file_cache_valid和open_file_cache_min_uses) - 若使用 XFS 文件系统,确保挂载参数含
inode64,allocsize=64k,提升多磁盘环境下 inode 分布与查找效率 - 禁用 access_log(或仅记录错误)、关闭 server_tokens,减少非必要系统调用对 I/O 调度器的干扰


















