keys_zone内存大小需按实际key数量计算,1MB约存8000个key;应根据业务唯一URL量(如日均200万key需250m),结合proxy_cache_key粒度与日志统计确定,并注意不可动态扩容、跨设备链接等约束。

keys_zone 内存大小不是拍脑袋决定的
keys_zone 分配的内存只存缓存 key 和元数据(比如访问次数、过期时间),不存响应体本身。1MB 共享内存 ≈ 存 8000 个 key。如果你的业务每秒产生 100 个唯一 URL,按 1 小时内不重复计算,就是 36 万 key;按 1 天算,就是 864 万 key —— 这时候 keys_zone=my_cache:1m 显然不够,会频繁淘汰 key,导致缓存命中率骤降。
怎么算出实际需要的 keys_zone 大小
先确认你最关心的缓存粒度:是按 $uri?还是带完整 query 的 $scheme$host$uri$is_args$args?粒度越细,key 越多。再结合业务日志估算:
- 用
awk '{print $7}' access.log | sort -u | wc -l粗略统计一天内独立 URI 数量 - 若启用了
proxy_cache_key "$scheme$host$uri$is_args$args",再用awk -F'"' '{print $2}' access.log | awk '{print $1,$2}' | sort -u | wc -l估算带参数的唯一请求量 - 把结果除以 8000,向上取整,就是所需 MB 数。例如 200 万个唯一 key → 至少
keys_zone=my_cache:250m
配置时容易忽略的三个硬约束
proxy_cache_path 的 keys_zone 值一旦写死,重启 Nginx 后无法动态扩容;且该内存区域在 worker 进程间共享,但不跨机器。常见踩坑点:
安装并运行 Aperture(Lightning Labs 的 L402 闪电反向代理),用于创建 L402 付费墙、配置付费 API 端点、为其他代理托管付费内容或测试 L402 认证流程。
-
proxy_temp_path和proxy_cache_path必须在同一个文件系统分区,否则缓存写入失败(错误日志里会出现open() "/path/to/cache/xxx" failed (18: Invalid cross-device link)) - 如果用
use_temp_path=off(推荐),Nginx 会直接把缓存文件写进proxy_cache_path目录,此时keys_zone内存不足只会导致 key 淘汰,但磁盘空间满会导致整个缓存失效 - 多个
server块共用同一个keys_zone名称时,key 是全局去重的;若误配成不同名称(如my_cache_v1/my_cache_v2),等于人为切分缓存池,浪费内存
上线前必须验证的两件事
光写对配置没用,得看它是否真按预期工作:
- 用
sudo nginx -t检查语法后,执行sudo ss -tulpn | grep :80确认 Nginx 已加载新配置(避免 reload 失败静默回退) - 访问一个已知接口后,立刻查
curl -I http://your-domain/test.jpg | grep N-Cache-Status(前提是配置了add_header N-Cache-Status $upstream_cache_status),返回HIT才说明 key 和缓存路径都通了
缓存 key 的内存分配是个“看不见但压垮性能”的点:太小,key 频繁踢出,命中率上不去;太大,又白白占着 worker 进程的共享内存,影响其他模块。真实业务中,建议从预估值起步,上线后用 nginx -V 2>&1 | grep -o 'built by.*' 确认版本,并持续观察 $upstream_cache_status 统计分布,再微调。










