page cache是内核层文件缓存,nginx缓存是应用层http响应缓存,二者层级互补;“二级缓存命中”指nginx读取磁盘缓存文件时因文件已被page cache缓存而免于真实i/o,需通过预热、调优vm参数、优化文件系统及nginx配置来保障其稳定驻留与高效利用。

Page Cache 是内核层的文件数据缓存,Nginx 缓存是应用层的 HTTP 响应缓存,二者本质不同、层级互补。所谓“二级缓存命中”并非标准术语,但实践中常指:Nginx 本该从磁盘读取缓存文件(如 /var/nginx/cache/...)时,因这些文件本身已被 Linux 内核缓存在 Page Cache 中,从而避免了真实磁盘 I/O,实现“缓存之上的缓存加速”。这种协同效应能显著提升 Nginx 缓存服务的吞吐与响应延迟。
要让 Page Cache 真正为 Nginx 缓存“托底”,关键不是调大某个参数,而是确保 Nginx 缓存文件持续驻留内存、被高效访问,并减少内核主动回收。
让 Nginx 缓存文件稳居 Page Cache
Nginx 默认以普通文件方式写入和读取缓存(如 proxy_cache_path 指定路径下的文件),这类文件天然进入 Page Cache。但若缓存目录过大、访问不均衡或系统内存紧张,内核会按 LRU 回收冷页,导致后续读取仍触发磁盘 IO。
- 用
vmtouch -t /var/nginx/cache主动预热整个缓存目录,把所有缓存文件元数据和内容页加载进内存(适合重启后或大促前) - 设置
vm.vfs_cache_pressure=50(默认100),降低 dentry/inode 缓存回收优先级,间接保护关联的 page cache 稳定性 - 避免在缓存盘上混用其他高 IO 应用(如数据库日志、临时编译目录),防止
kswapd因内存压力频繁扫描并回收缓存页
减少 Nginx 缓存文件的随机读开销
Nginx 查找缓存 key 时需解析哈希目录结构(如 levels=1:2 对应两级子目录),频繁 stat/open 操作容易产生大量小页读,易被内核视为低优先级而淘汰。
- 将缓存路径挂载为
noatime,nodiratime,relatime(推荐relatime),避免每次访问更新 atime 导致 page 脏化与额外 writeback - 使用
xfs或ext4文件系统,并确保inode64(XFS)或dir_index(ext4)启用,加速目录遍历,减少 page fault 次数 - 若缓存总量 proxy_cache_path 挂载到 tmpfs(内存文件系统),彻底绕过磁盘——但需注意断电丢失与 swap 风险
配合 Nginx 配置放大 Page Cache 效益
Page Cache 是否生效,最终取决于 Nginx 实际读的是不是“同一份缓存文件”。若配置不当,可能绕过缓存或频繁失效。
- 关闭
proxy_cache_lock on(除非强一致性要求),避免单个未命中请求阻塞后续并发请求,导致多进程重复读盘、加剧 page cache 竞争 - 启用
proxy_cache_background_update on,让过期缓存仍可命中并后台异步刷新,维持 page cache 热度不中断 - 在
log_format中加入$upstream_cache_status,配合grep "HIT" access.log | wc -l统计真实命中率;再用cat /proc/meminfo | grep -i "cached\|sreclaimable"观察 Cached 值是否随缓存增长稳定上升——若增长停滞,说明 page cache 未有效承接
监控是否真正在用 Page Cache
光看 free -h 的 “Cached” 不够,它包含 buffer、slab 等。精准验证 Nginx 缓存文件是否在内存中:
-
vmtouch -v /var/nginx/cache显示每个子目录的“Resident Pages”占比,95%+ 表示基本全驻留 -
cat /proc/<nginx_worker_pid>/maps | awk '$6 ~ /cache/ {print $1}' | xargs -I{} cat /proc/<nginx_worker_pid>/smaps | grep -E "^(MMU|Pss|Referenced):" | paste - - -</nginx_worker_pid></nginx_worker_pid>查看 worker 进程实际引用的缓存页物理内存用量 -
perf record -e 'syscalls:sys_enter_read' -p $(pgrep nginx) -- sleep 10 && perf script抽样分析 read 系统调用耗时,若多数 1ms 则极可能落盘
不复杂但容易忽略











