nginx在numa架构上的性能瓶颈在于跨节点内存访问延迟,调优核心是让每个worker进程严格绑定本地cpu与本地内存:先用lscpu、numactl --hardware和cat /sys/devices/system/node/node*/cpulist确认真实拓扑;worker_processes设为单节点物理核数(如双路16核/节点则设16),禁用auto;worker_cpu_affinity按节点分段配置掩码;必须用numactl --cpunodebind --membind启动;最终通过numastat验证local_node>95%、numa_foreign≈0。

Nginx 在 NUMA 架构服务器上的性能瓶颈,往往不在 CPU 算力,而在跨节点内存访问带来的延迟激增。调优进程总数不是“越多越好”,而是要让每个 worker 进程严格运行在本地 CPU + 本地内存的组合上。关键不是总数,而是如何按 NUMA 节点合理切分、绑定并验证。
先看清硬件真实拓扑,再动配置
别依赖逻辑核数或 auto 推断。必须执行三步确认:
- lscpu | grep -E "(Socket|Core|NUMA)" → 查清插槽数(Socket)、每槽物理核数、NUMA 节点总数
- numactl --hardware → 明确每个 node 的 CPU 编号范围(如 node 0: CPUs 0–15)和本地内存容量
- cat /sys/devices/system/node/node*/cpulist → 精确到每个核心归属,避免掩码错位
特别注意:若 BIOS 中启用了 Node Interleaving,numactl 会显示单个大节点,实际已丧失 NUMA 局部性——必须进 BIOS 关闭该选项。
worker_processes 必须设为单节点物理核心数
例如双路 32 核服务器(每路 16 物理核),应设:
- worker_processes 16(而非 auto、32 或 64)
- 更稳妥可设为 8~12,留出资源余量给系统进程与中断处理
设为 auto 是常见错误:它只读 /proc/cpuinfo 总数,不感知 NUMA 边界,实测易导致一半 worker 被调度到远端 node,numa_foreign 指标翻倍。
CPU 与内存必须同步绑定,缺一不可
仅靠 worker_cpu_affinity 绑定 CPU 不够,Nginx 无法控制 malloc 分配的内存落在哪个 node:
-
worker_cpu_affinity 要按节点分段写。例如 node 0 有 CPU 0–15,则用 16 位掩码:
worker_cpu_affinity 0000000000000001 0000000000000010 0000000000000100 ...(共 16 组,对应 16 核) - 必须用 numactl 启动主进程,强制内存亲和:
/usr/bin/numactl --cpunodebind=0 --membind=0 /usr/sbin/nginx -g 'daemon on; master_process on;'
若需双节点部署,改用 --cpunodebind=0,1 --membind=0,1,但更推荐单节点部署 + 外部负载分发,避免共享内存区跨节点访问。
验证是否真正落地,看内存路径而非 CPU ID
不能只看 taskset 或 ps 输出的 CPU 绑定结果。核心指标是内存访问路径:
- 运行 numastat -p $(pgrep nginx)
- 关键列:local_node 应 >95%,numa_foreign 应接近 0
- 若 foreign 偏高,说明仍有跨节点内存分配,需检查 BIOS 设置、numactl 参数或掩码位数是否匹配总 CPU 数。











