keys_zone大小应按实际去重key数量精确计算,而非依赖并发或流量;每个key约64字节,1mb可存7500–8500个平均256字节的key,需从日志抽样统计真实key数并预留15–20%冗余。

keys_zone 共享内存大小不能靠“海量”这种模糊概念来配,得算清楚你真正要长期保留在缓存中的唯一 key 有多少个。它不随并发涨,也不随流量翻倍,只和 key 的去重总数直接相关。
先搞清 keys_zone 存的是什么
它只存两样东西:缓存 key 字符串(比如 $scheme$host$uri$is_args$args 拼出来的结果),以及每个 key 对应的少量元数据(过期时间、状态、引用计数等)。不存响应体、不存 header、不随请求实时增长。
- 默认每个 key 占约 64 字节 slot,但实际受哈希结构、碎片、key 长度影响
- 官方经验值:1 MB 共享内存 ≈ 稳定容纳 7500–8500 个平均长度(约 256 字节)的 key
- 如果你的 key 包含长 cookie、随机 token 或毫秒级时间戳,实际容量会明显缩水
按业务真实 key 数量估算
别猜 QPS 或日活,直接从日志里抽样统计去重后的 proxy_cache_key 值:
安装并运行 Aperture(Lightning Labs 的 L402 闪电反向代理),用于创建 L402 付费墙、配置付费 API 端点、为其他代理托管付费内容或测试 L402 认证流程。
- 静态资源(如 /css/app.css、/img/logo.png)→ key 极少且固定,几千个 key 配 10m 就够
- API 接口按用户 ID 缓存(如
$uri?$uid),活跃用户 50 万 → 至少 500000 ÷ 8000 ≈ 62.5m,建议设为keys_zone=api:80m - 搜索页带未归一化参数(
/search?q=test&t=1713456789)→ 每秒 10 个不同 t 值,1 小时就生成 36000 个 key,10m 很快打满
避开常见配置陷阱
keys_zone 不足时 Nginx 不报错,但表现很隐蔽:
-
$upstream_cache_status长期显示 MISSED,即使后端返回了Cache-Control: public, max-age=3600 - 磁盘缓存目录文件持续堆积,但共享内存中 key 数量停滞不增
- 命中率低、后台更新频繁、锁竞争升高,却查不出明确错误日志
- 超过 200m 的 keys_zone 很少必要,反而可能触发内核 slab 分配延迟
上线前验证与上线后观察
最稳妥的方式是实测:
- 上线前取 10 分钟真实流量,提取所有去重
proxy_cache_key,统计总数再换算 - 上线后用
curl -I URL | grep N-Cache-Status抽样看命中状态趋势 - 定期检查
nginx -s stats(需启用 stub_status)或通过 OpenResty 的 shared_dict 查 key 数量 - 预留 15–20% 冗余空间,例如算出来要 64m,就配
keys_zone=mycache:80m










