在numa架构服务器上,nginx worker_processes应按numa节点均分并绑定本地cpu与内存,如双路服务器设为16(每节点8个),配合worker_cpu_affinity和numactl强制内存亲和,再调优文件数、连接数等参数,最后用numastat和perf验证本地内存分配有效性。

在单机多路(Multi-Socket)NUMA架构服务器上,Nginx的worker_processes配置不能只看“总核心数”,必须结合内存访问拓扑来设计。盲目设为auto或简单等于逻辑核数,反而会因跨节点内存访问导致延迟飙升、吞吐不升反降。真正有效的调优,是让每个Worker进程绑定到**本地CPU核心+本地内存节点**,实现低延迟、高带宽的数据路径。
先识别NUMA拓扑,再定worker数量
执行numactl --hardware查看真实布局。典型双路服务器可能显示:
- Node 0:CPU 0–15,本地内存 64GB
- Node 1:CPU 16–31,本地内存 64GB
此时worker_processes不应设为32(全部核心),而应按节点均分——例如设为16,并确保每8个Worker服务一个NUMA节点。更稳妥的做法是:
- 设
worker_processes 16(即每节点8个) - 用
worker_cpu_affinity将前8个Worker严格绑定Node 0的CPU(如0000000000000001 0000000000000010 ...) - 后8个绑定Node 1的CPU(如
00000000000000010000000000000000 ...)
用numactl启动,强制内存亲和
Nginx自身不支持内存节点绑定,必须靠外部封装。在systemd服务中修改/etc/systemd/system/nginx.service.d/override.conf:
[Service] ExecStart= ExecStart=/usr/bin/numactl --cpunodebind=0 --membind=0 /usr/sbin/nginx -g 'daemon off;' # 第二组Worker需另起服务实例,或改用脚本分片启动
若需单实例管理全部Worker,可写启动脚本,对不同Worker子集分别调用numactl,再通过nginx -s reload协同控制。
配套关键参数必须同步调整
CPU与内存绑定只是第一步,还需防止资源错配引发瓶颈:
-
worker_rlimit_nofile设为100000以上,并同步调高系统fs.file-max和用户级nofile限制 -
worker_connections建议设为32768以内,避免单Worker内存占用过高(每个连接约240字节) - 禁用
accept_mutex off(高并发下开启可减少锁争用,但NUMA场景需实测验证) - 静态文件服务务必启用
sendfile on和tcp_nopush on,减少跨节点内存拷贝
验证是否真正生效
仅看taskset -cp不够,必须确认内存分配路径:
- 查Worker进程PID:
ps -eo pid,comm,args | grep 'nginx: worker' - 查其NUMA节点归属:
numastat -p PID→ 观察Node 0 Total和Node 1 Total占比,理想情况应>95%集中在绑定节点 - 查内存页分布:
cat /proc/PID/status | grep Mems_allowed_list,应只显示对应节点的CPU编号范围 - 压测时用
perf top -p PID观察__alloc_pages_slowpath调用频次,越低说明本地内存分配越稳定











