keys_zone内存用量取决于缓存key数量与长度,与并发量无关;1MB约存8000个key(按平均256字节计),需按预期长期缓存的唯一key总数估算,而非QPS。

keys_zone 内存用量不能按并发量线性估算,它只跟缓存 key 的数量和长度有关,跟当前有多少请求在跑完全无关。
keys_zone 实际存的是什么
它在共享内存中只存两样东西:每个缓存项的 key 字符串(比如 $scheme$host$uri$is_args$args 生成的结果),以及少量元数据(如访问次数、过期时间、状态标记)。不存响应体、不存 header、不随请求数实时增长。
官方文档明确说:1m 共享内存约可存 8000 个 key。这个数字基于平均 key 长度 ≈ 256 字节 —— 如果你用的 proxy_cache_key 包含长 cookie 或动态参数,实际能存的 key 数会更少。
- key 越短、越固定(比如纯静态路径),单位内存存得越多
- key 含
$cookie_sessionid或$arg_token这类变量,长度不可控,key 数量上限会明显下降 - 并发量高但 key 重复率高(比如 1000 个用户反复刷首页),共享内存几乎不涨
- 并发量低但每个请求 key 都不同(比如带唯一 timestamp 参数),哪怕只有 10 个请求,也可能撑爆 1m zone
怎么算够不够用:看 key 总数,不是看 QPS
真正要估算的是「你预期长期保留在缓存中的不同资源 URL 总数」,而不是每秒多少请求。例如:
- 静态资源目录有 5 万个文件,且都走同一
location,proxy_cache_key不含用户变量 → 约需50000 ÷ 8000 ≈ 6.25m,建议配keys_zone=static:10m - API 接口返回内容按用户 ID 缓存,活跃用户 20 万 → 至少预留
200000 ÷ 8000 = 25m,再加冗余设为keys_zone=api:32m - 没做 key 归一化,
GET /search?q=test&t=1713456789和&t=1713456790被当成两个 key → 即使 QPS 只有 10,一小时也能生成 36000 个 key,10m很快打满
容易被忽略的三个坑
keys_zone 内存不足时,Nginx 不报错,但新 key 写不进共享内存,导致缓存始终 MISS,而磁盘缓存目录里文件还在悄悄堆积(因为 proxy_cache_path 没限制 key 存储,只限制 value 存储)。
- 用
nginx -t检查不出问题,ps aux | grep nginx也看不出异常 -
$upstream_cache_status会长期显示MISSED,即使后端返回了Cache-Control: public, max-age=3600 - 磁盘上
/data/nginx/tmp-test/下文件越来越多,但keys_zone对应的共享内存里 key 数停滞不增 —— 这是典型征兆
最稳妥的做法:上线前用真实流量采样 10 分钟,提取所有去重后的 proxy_cache_key 值,统计总数,再按 8000/key_per_m 估算;上线后定期用 curl -I http://your.site/any-path | grep N-Cache-Status 观察命中率变化趋势,比死盯并发数字有用得多。











