nginx共享缓存通过master预分配posix共享内存、worker mmap共址访问实现,无复制同步;回收由cache manager或lru机制自动触发,异常退出不影响共享内存有效性。

Nginx 多进程架构中,共享缓存资源(如 proxy_cache、ssl_session_cache)不靠进程间复制或传递实现“共享”,而是由 master 进程统一预分配一块操作系统级共享内存(shared memory),所有 worker 进程通过 mmap 映射到同一物理地址空间,直接读写其中的数据结构。回收也不依赖主动清理,而是由内核和 Nginx 自身机制协同完成。
共享缓存的内存分配由 master 统一完成
master 进程在启动阶段解析配置(如 proxy_cache_path ... keys_zone=my_cache:64m 或 ssl_session_cache shared:SSL:10m),调用 mmap(MAP_SHARED | MAP_ANONYMOUS) 分配指定大小的 POSIX 共享内存区。该区域被所有 fork 出来的 worker 进程继承,每个 worker 以相同偏移量访问同一块内存中的哈希表、计数器等结构。
-
keys_zone=my_cache:64m中的 64m 是纯内存开销,专用于存储缓存键(key)及其元数据(如过期时间、引用计数),不包含实际响应体文件; - 实际响应体以文件形式落盘(如
/var/cache/nginx/...),由 Linux Page Cache 自动缓存热数据,不属于共享内存范畴; - 同名共享内存区大小必须一致,重复声明会报错,确保映射一致性。
worker 进程不分配、不释放共享内存,只做并发读写
worker 不参与共享内存的生命周期管理,所有操作均基于已映射的地址:
- 缓存写入时,通过哈希函数定位槽位,用自旋锁(spinlock)保护临界区,避免多 worker 写冲突;
- 缓存读取时,直接查哈希表,无网络通信、无广播同步,毫秒级命中;
- 没有“释放某条缓存”的 API,淘汰由后台进程或 LRU 机制触发,例如:
- cache manager 进程定期扫描
inactive=60m的条目并删除; - 当
max_size=10g达限时,按 LRU 清理冷数据; - ssl_session_cache 不设 inactive,但会根据 TTL 自动失效。
- cache manager 进程定期扫描
异常退出与共享内存的兜底保障
共享内存本身由内核管理,不受 worker 生死影响:
- 即使某个 worker 崩溃或被 kill -9,其对共享内存的修改仍有效,其他 worker 可继续使用;
- master 进程不负责回收共享内存,它只在 reload 或 shutdown 时显式释放(调用 munmap);
- 若 Nginx 非正常终止(如断电),共享内存可能残留,但下次启动会检测并覆盖或重建,不影响服务;
- 系统级限制(如
/proc/sys/kernel/shmall)需匹配总共享内存需求,否则分配失败报错。
配置与监控的关键点
-
keys_zone容量要匹配热点 key 数量:64MB 约支持 12–25 万 key,miss 率持续高于 15% 应优先扩容; - 使用
nginx -T | grep keys_zone确认实际生效配置; - 通过
curl -I http://example.com观察X-Cache: HIT/MISS,结合proxy_cache_miss指标定位瓶颈; - Windows 平台不支持 POSIX shm,ssl_session_cache 回退为 per-worker builtin 模式,复用率大幅下降,建议设
worker_processes 1或迁移到 Linux。











