keys_zone是nginx缓存的索引内存区,需按真实唯一key数量精准配置:每8000个key约需1mb,再加15%–20%冗余;它仅存key字符串、过期时间与状态标记,不存响应体或响应头;配小则命中率骤降,配大则浪费内存并引发分配延迟。

keys_zone 不是随便填个数字就行的内存参数,它是 Nginx 缓存能否高效运转的“索引大脑”。配小了,缓存命中率断崖下跌;配大了,既浪费内存,又可能引发内核分配延迟。关键在于算准你真正需要长期管理的唯一缓存键(key)数量。
keys_zone 存什么、不存什么
它只存三类轻量信息:缓存 key 字符串(比如 $scheme$host$uri$is_args$args 拼出来的完整请求标识)、该 key 对应的过期时间、状态标记(如是否正在后台更新)。不存响应体、不存响应头、不随每次请求增长。相当于图书馆的索引卡柜——卡在,书才“算有”;卡丢了,哪怕文件还在磁盘上,Nginx 也当它不存在。
按真实 key 数量估算大小,不是按流量或并发
1 MB 共享内存稳定支持约 7500–8500 个平均长度的 key(含元数据)。计算公式很简单:
- 从 access 日志中提取真实使用的 proxy_cache_key 值,去重统计总数。例如:awk -F'"' '{print $2}' access.log | awk '{print $1,$2}' | sort -u | wc -l
- 用总数除以 8000,向上取整,得到理论最小 MB 数
- 再加 15%–20% 冗余(应对 key 长度波动或突发新增),就是建议配置值
举例:日志统计出 48 万个唯一 key → 480000 ÷ 8000 = 60 → 建议设为 keys_zone=my_cache:72m(60 × 1.2)。
不同业务场景的典型参考值
- 静态资源(CSS/JS/图片):key 极少且固定,keys_zone=static:10m–20m 足够支撑数万文件
- 商品详情页或文章页(按 URI 缓存):日均百万级页面,活跃 key 约 40 万 → 推荐 keys_zone=page_cache:50m
- 用户维度 API(如 /api/profile?uid=123):活跃用户 80 万 → 至少 keys_zone=api_cache:100m
- 带未归一化时间戳或随机参数的搜索接口:每秒生成新 key,需严格归一化或限制缓存粒度,否则 keys_zone=10m 都可能迅速打满
必须避开的硬性陷阱
- 名称不一致:proxy_cache 指令中的名称(如 proxy_cache api_cache)必须与 proxy_cache_path 中 keys_zone 的名称(如 keys_zone=api_cache:20m)完全一致,否则缓存彻底失效
- 不可动态扩容:keys_zone 大小写死后,只能 reload 或重启生效,运行中无法调整
- 不跨 worker 共享,更不跨机器:它是本机所有 worker 进程共享的内存区,不是分布式缓存
- 过小的表现很隐蔽:不会报错,但 $upstream_cache_status 长期显示 MISSED,磁盘缓存文件持续堆积而内存 key 数停滞











