nginx重启后缓存“丢失”实为keys_zone索引未重建或路径权限异常所致,磁盘缓存文件仍存在;需检查缓存目录文件数量与归属、error log中cache loader状态、x-cache-status响应头及selinux等系统限制。

一、确认缓存文件是否还在磁盘上
proxy_cache 是磁盘持久化的,重启不删文件——前提是没配 inactive 过短或 max_size 触发自动清理。
- 进你配置的缓存目录,比如
/var/cache/nginx/query/,执行:find . -type f | wc -l—— 看有没有成百上千的文件 - 挑一个文件用
stat查修改时间:stat ./0/32/ab3f—— 如果 mtime 是重启前的时间,说明文件没被删 - 再检查该目录归属:
ls -ld /var/cache/nginx/query—— 必须是nginx:nginx(或实际 worker 用户),否则启动后无法读取
二、检查 keys_zone 是否成功加载
keys_zone 是缓存的“内存索引区”,它不存数据,但存所有缓存项的 key、过期时间、文件位置等元信息。Nginx 启动时会扫描缓存目录并重建这个索引——但只在首次启动或缓存目录结构变更时做一次 loader 操作,且有超时和并发限制。
- 查 error log 是否有 loader 相关报错:
grep "cache loader" /var/log/nginx/error.log
常见如cache loader process XXX exited on signal 15或cache loader process XXX exited with code 0(正常结束) - 确认
proxy_cache_path中的loader_files、loader_sleep、loader_threshold是否合理(默认值一般够用,但若缓存文件超 10 万+,可能 loader 未扫完就退出) - 临时加日志验证索引是否生效:
在 location 中加add_header X-Cache-Status $upstream_cache_status;,curl 请求看返回是不是HIT;如果全是MISS或EXPIRED,大概率索引没建好
三、排除路径与运行环境干扰
即使文件存在、索引也加载了,也可能因路径配置错误或系统限制导致“看不见”缓存。
- 确认
proxy_cache_path和proxy_temp_path在同一文件系统(df -P /path对比 dev);跨文件系统会导致缓存写入失败,后续也无法读取 - 检查是否启用了
use_temp_path=off(推荐开启);若为on且proxy_temp_path权限不对或磁盘满,Nginx 可能跳过缓存写入,甚至拒绝读取旧缓存 - systemd 管理的 Nginx 要注意:如果配置了
PrivateTmp=yes,会导致每次启动都用新 tmp 目录,proxy_temp_path实际不可达 —— 改为PrivateTmp=no并重载 daemon - SELinux 或 AppArmor 开启时,可能阻止 Nginx 访问缓存目录;临时设为 permissive 模式测试:
setenforce 0(仅调试用)











