关键是小文件过多导致 inode 耗尽,需用 df -i 确认、find 统计小文件占比,检查 levels 和 proxy_cache_key 合理性,确保 inactive 生效,并清理旧文件及优化缓存策略。

排查 proxy_cache 占用过多 inode 资源,关键不是看磁盘空间,而是看缓存目录下是否产生了海量小文件——每个缓存项(哪怕只有几百字节)都会消耗一个 inode。一旦 inode 耗尽,即使磁盘还有空间,Nginx 也会因无法创建新缓存文件而返回 500 或静默失败。
确认 inode 是否真的耗尽
先验证问题是否存在,避免误判:
- 运行
df -i /path/to/cache(把/path/to/cache替换为proxy_cache_path实际路径),重点看 IUse% 是否接近或达到 100% - 对比
df -h和du -sh:如果磁盘使用率很低但df -i显示满载,基本可锁定是小文件堆积 - 执行
find /path/to/cache -type f | wc -l查总文件数;再用find /path/to/cache -type f -size -1k | wc -l看小于 1KB 的文件占比——若超 70%,就是典型 inode 压力来源
定位缓存路径与层级配置是否合理
inode 消耗过快,往往源于 levels 设置不当或 key 设计导致哈希散列不均:
FastAPI + Flask 混合部署最佳实践,解决路由定义、API 代理等常见问题,适用于同时运行 FastAPI API 与 Flask 前端的场景。
- 检查
proxy_cache_path行中的levels参数,例如levels=1:2会生成最多16 × 256 = 4096个子目录;若设成levels=1:2:2,子目录数暴增至16 × 256 × 256 ≈ 100 万,反而增加目录树开销且不必要 - 用
find /path/to/cache -maxdepth 1 -type d | wc -l查一级目录数量,正常应在 16 左右;若远超此数(如上百),说明levels配置错误或被覆盖 - 检查
proxy_cache_key是否包含易变字段(如时间戳、随机参数、用户 ID),这会导致同一资源被反复缓存为不同 key,快速生成冗余小文件
检查缓存淘汰机制是否失效
大量“冷”缓存未被清理,是 inode 持续增长的主因:
- 确认
proxy_cache_path中是否设置了inactive=XXm(如inactive=30m),该参数决定多久未被访问的缓存条目会被自动删除 - 手动验证淘汰是否生效:运行
ls -t /path/to/cache/*/*/* 2>/dev/null | tail -20,查看最旧的缓存文件修改时间;若比inactive值长得多,说明淘汰未触发(常见于 Nginx 未重载配置或 worker 进程异常) - 注意
max_size只控制磁盘容量上限,不控制 inode 数量;即使磁盘没满,inode 也可能先耗尽
临时缓解与长期优化建议
发现已满时需快速释放,再从配置层面堵住源头:
- 立即清理:用
find /path/to/cache -type f -mtime +1 -delete删除 1 天前的文件(先测试不加-delete);更安全可用分批删:find /path/to/cache -type f -print0 | head -z -n 5000 | xargs -0 rm -f - 调整 key 粒度:对静态资源(如 JS/CSS),去掉 query string 中的版本号以外参数,例如用
$scheme$request_method$host$uri替代完整$request_uri - 限制单缓存项大小:加上
proxy_cache_max_range_offset 1m,防止 Range 请求为每个片段都建独立缓存文件 - 监控落地:写脚本定期采集
find /path/to/cache -type f | wc -l并上报 Prometheus,设置 inode 文件数 > 50 万告警










