nginx共享内存由master进程在启动时通过mmap分配并由worker继承,配置需显式声明zone,大小固定不可运行时调整,生命周期由master全程管控,不依赖ipc或磁盘。

Master 进程不参与运行时读写,只负责创建、初始化和生命周期管理——共享内存是它分配给所有 worker 的“公共白板”,worker 自己上去写、自己上去读,master 从不插手具体操作。
启动时一次性分配并继承
Master 在启动阶段调用 mmap(MAP_SHARED | MAP_ANONYMOUS) 分配一块匿名内存,不绑定文件,内容全零。随后 fork 出 worker 进程,借助 Linux 写时复制(COW)机制,所有 worker 自动映射到同一物理内存页。虚拟地址可以不同,但 Nginx 内部统一用相对偏移量定位数据,避免指针失效。
配置驱动,zone 必须显式声明
共享内存不是默认开启的功能,必须通过模块指令显式定义命名区域(zone):
- 限流:limit_req_zone $binary_remote_addr zone=ip_limit:10m rate=10r/s;
- 连接限制:limit_conn_zone $binary_remote_addr zone=conn_limit:10m;
- 缓存元数据:proxy_cache_path /cache levels=1:2 keys_zone=cache_one:50m;
- SSL 复用:ssl_session_cache shared:SSL:10m;
- Lua 字典:lua_shared_dict rate_limit 10m;
Master 解析这些指令后,调用 ngx_shared_memory_add() 注册 zone,并在初始化 cycle 时完成 mmap 分配。没有 zone 声明,就没有共享内存。
大小固定,不可运行时调整
每个 zone 的大小在配置中写死,上线前必须预估:
- keys_zone 每 1MB 约存 8000–12000 个 key(取决于 key 长度)
- 限流/连接 zone 按 key 数 ×(结构体大小 + 哈希冗余)× 1.5 估算
- 过小 → 哈希冲突高、条目被 LRU 强制淘汰;过大 → slab 效率下降、浪费内存
reload 时若 zone 名称或大小变更,Master 会新建 zone,旧 zone 待 worker 优雅退出后才释放;若未改动,旧 zone 可复用。
不参与锁竞争,但控制锁存在性
Master 不执行加锁/解锁动作,也不处理并发逻辑。但它决定了锁是否可用:
- 锁变量(如 ngx_shmtx_t)就放在共享内存块头部,由 slab 分配器管理
- worker 用原子指令(CAS 或 fetch_add)操作该变量,实现无系统调用的自旋锁
- reload 失败(如 zone 太小)时,Master 直接拒绝启动,防止运行时锁异常
- 模块卸载前,Master 确保无活跃引用,否则可能触发 core dump
退出与重载时的清理责任
共享内存生命周期完全由 Master 掌控:
- worker 进程退出不释放任何共享内存,哪怕只剩一个 worker 在跑
- reload 时,Master 启动新 cycle 并尝试分配新 zone;旧 worker 收到 SIGQUIT 后逐步退出,期间继续服务,直到无活跃请求才释放旧 zone
- nginx -s stop 时,Master 发送 SIGTERM 给所有 worker,等待其自然退出后再 munmap
整个过程不依赖 IPC、不经过网络、不走磁盘,纯靠内核 mmap 和 fork 继承完成,高效且确定。











