Nginx 内存池与共享内存优化
Nginx 通过内存池管理单请求内存分配,通过共享内存实现多 worker 进程间数据共享。
内存池优化
内存池复用
C
// 创建请求级内存池
ngx_pool_t *pool = ngx_create_pool(1024, r->connection->log);
// 使用内存池分配
void *p = ngx_palloc(pool, size);
// 请求结束销毁
ngx_destroy_pool(pool);
内存池参数
| 参数 | 默认值 | 说明 |
|---|---|---|
| connection_pool_size | 256/512 | 连接级内存池 |
| request_pool_size | 4k | 请求级内存池 |
| large_client_header_buffers | 4 × 8k | 大请求头缓冲 |
优化配置
nginx
events {
connection_pool_size 1024; # 增大连接池
}
http {
request_pool_size 8k; # 增大请求池
large_client_header_buffers 8 16k; # 大请求头
}
内存池过大会浪费内存,过小会导致频繁分配。应根据平均请求大小调整。
共享内存机制
共享内存 Zone
nginx
http {
# 限流共享内存
limit_req_zone $binary_remote_addr zone=api:10m rate=10r/s;
# 限连接共享内存
limit_conn_zone $binary_remote_addr zone=perip:10m;
# upstream 共享内存(Nginx Plus)
upstream backend {
zone backend 64k;
server 10.0.0.1:8080;
}
# 缓存共享内存
proxy_cache_path /data/nginx/cache levels=1:2 keys_zone=my_cache:10m max_size=1g;
}
共享内存计算
| Zone 类型 | 大小计算 |
|---|---|
| limit_req_zone | IP 数 × 128 字节 |
| limit_conn_zone | IP 数 × 64 字节 |
| upstream zone | server 数 × 256 字节 |
| proxy_cache keys_zone | 缓存项数 × 256 字节 |
| proxy_cache max_size | 磁盘缓存上限 |
共享内存创建
C
// 创建共享内存
ngx_shm_zone_t *zone;
zone = ngx_shared_memory_add(cf, &name, 0, &ngx_http_limit_req_module);
if (zone == NULL) {
return NGX_CONF_ERROR;
}
zone->data = ctx;
zone->init = ngx_http_limit_req_init_zone;
zone->shm.size = size;
共享内存数据结构
红黑树存储
C
共享内存布局:
[ngx_slab_pool_t] // slab 分配器头部
[ngx_rbtree_t] // 红黑树根节点
[sentinel] // 哨兵节点
[data nodes...] // 数据节点
原子操作
C
// 原子递增
ngx_atomic_fetch_add(lock, 1);
// 互斥锁
ngx_shmtx_lock(&shpool->mutex);
// 临界区操作
ngx_shmtx_unlock(&shpool->mutex);
共享内存通过 slab 分配器管理,红黑树实现高效查找,互斥锁保证并发安全。
跨进程同步
无锁设计
nginx
// 读操作无锁
ngx_atomic_int_t count = *counter;
// 写操作加锁
ngx_shmtx_lock(&shpool->mutex);
*counter += 1;
ngx_shmtx_unlock(&shpool->mutex);
状态同步
nginx
worker 1: 读取共享内存 → 获取最新状态
worker 2: 更新共享内存 → 广播变更
worker 3: 读取共享内存 → 感知变更
无需 IPC,所有 worker 直接读写共享内存
调优策略
内存池调优
Bash
# 高并发场景
events {
connection_pool_size 2048;
}
http {
request_pool_size 16k;
reset_timedout_connection on; # 快速回收超时连接
}
共享内存调优
text
# 限流 zone 大小
limit_req_zone $binary_remote_addr zone=api:100m rate=100r/s;
# 缓存 zone
proxy_cache_path /data/cache levels=1:2 keys_zone=cache:50m max_size=10g;
内存监控
text
# 查看共享内存使用
ipcs -m
# 查看进程内存
pmap $(cat /run/nginx.pid) | grep total
要点总结
- 内存池通过 ngx_create_pool/ngx_palloc/ngx_destroy_pool 管理,按请求/连接生命周期复用
- 共享内存通过 slab 分配器 + 红黑树实现高效存储,支持多 worker 进程并发访问
- Zone 大小应根据预期状态数计算(IP 数 × 128 字节)
- 共享内存读写通过互斥锁保护,读操作可无锁进行
- 高并发场景应增大 connection_pool_size 和 request_pool_size,减少内存碎片
📝 发现内容有误?点击此处直接编辑