关键在于用 proxy_cache_min_uses 过滤长尾请求以保护 SSD:对 URI 高度离散、单次访问即淘汰的请求设 min_uses≥2,静态资源保持为 1,随机参数接口直接 bypass 缓存,并精简 cache_key、启用 cache_lock 与合理 inactive/max_size 配置。

直接设一个固定值不能保护 SSD,关键在于用 proxy_cache_min_uses 避免大量低频请求反复写入缓存文件 —— 每次写缓存都是一次磁盘 I/O,而长尾请求(如带随机参数的埋点、404 路径、单次调试 URL)几乎只访问一次,却各自触发一次落盘,持续消耗 SSD 的 P/E 周期。
识别真正该过滤的长尾请求
不是所有“访问少”的请求都要拦,重点是那些 URI 高度离散、单 key 终身只被访问 1–2 次、但总体请求数占比高、缓存命中率长期接近 0 的集合:
- 用 Nginx 日志统计 URI 频次:开启
log_format记录$request_uri和$status,再用awk '{print $7}' access.log | sort | uniq -c | sort -nr | head -50查看高频低复用路径(如/log?uid=xxx&t=1713224400456&r=abc123) - 观察
$upstream_cache_status:添加add_header X-Cache-Status $upstream_cache_status;,采样发现某类路径长期返回MISS且无后续HIT,就是典型的“写了一次就丢” - 检查
inactive淘汰速度:如果proxy_cache_path中设置inactive=60m,但大量缓存条目在几秒内就被清理,说明它们根本没被再次访问过,正是min_uses应该拦截的对象
按路径价值分层设值,不搞一刀切
全局统一设成 3 或 5 容易误伤中频内容,也起不到保护 SSD 的效果。应结合路径语义和访问特征差异化配置:
-
静态资源(.js/.css/.png):保持
proxy_cache_min_uses 1,它们天然高复用,早缓存反而减少重复回源和磁盘读 -
列表页或频道页(/news/list?page=1):设为
2或3,过滤掉爬虫试探、误点、单次浏览等噪声 -
详情页(/article/12345):设为
2,兼顾新内容冷启动与长尾淘汰 -
含随机参数的接口(/api/log?ts=...&r=...):不依赖
min_uses,改用map或if直接跳过proxy_cache指令,彻底避免生成 cache key
必须配套的关键配置
单独调高 min_uses 不仅无效,还可能加重后端压力。要真正降低无效磁盘写入,需组合以下机制:
-
精简
proxy_cache_key:剔除干扰字段(如$args中的utm_source、_t、r=等),确保语义相同的请求归为同一 key,否则min_uses对每个变体单独计数,失去意义 -
启用
proxy_cache_lock on:防止多个未缓存请求同时回源,避免后端被突发流量打垮,也减少重复响应写入磁盘的机会 -
用
proxy_cache_bypass显式绕过不可缓存请求:例如proxy_cache_bypass $arg_nocache $cookie_admin,让调试、管理类请求完全不参与缓存逻辑 -
配合
inactive和max_size:比如inactive=30m max_size=5g,让冷数据快速释放空间,避免 SSD 长期承载大量“僵尸缓存”
验证是否真在保护 SSD
不要只看命中率,重点观察磁盘写入行为是否下降:
- 用
iostat -x 1监控%util和wr_sec/s,对比调优前后写入量变化 - 检查 Nginx 缓存目录下文件增长速率:
find /var/cache/nginx -type f | wc -l每小时执行一次,若长尾请求多,未调优时该数字会快速攀升 - 通过
X-Cache-Status头统计MISS中属于MIN_USES类型的比例(Nginx 1.23+ 支持更细粒度状态码),确认策略生效











