必须用numactl启动Nginx主进程才能绑定CPU和内存,因worker_cpu_affinity仅限制CPU调度不控制内存分配,未绑定内存时worker仍可能从远端NUMA节点分配内存导致延迟倍增。

只配 worker_cpu_affinity 不够,多路 NUMA 服务器上必须用 numactl 启动 Nginx 主进程,才能同时绑定 CPU 和内存——否则 worker 即便跑在 Node 0 的核上,仍可能从 Node 1 分配内存,访存延迟翻倍,QPS 卡死。
为什么单靠 worker_cpu_affinity 会失效
它只告诉内核“这个 worker 能在哪几个 CPU 上跑”,但不控制内存分配策略。即使你用 0001 0010 0100 1000 把前 4 个 worker 全绑在 Node 0 的物理核上,只要主进程没限制内存域,这些 worker 的堆、缓存区、SSL 上下文等仍可能从 Node 1 分配。
-
cat /proc/<pid>/status | grep Mems_allowed</pid>返回00000003(两个节点都开)→ 内存本地性未生效 -
taskset -cp <pid></pid>显示绑定成功,但perf record -e mem-loads,mem-stores仍有大量远程访存 → 实际性能已受损
正确启动方式:numactl 必须作用于 master 进程
Nginx worker 继承 master 的 NUMA 策略,所以控制点只有一个:master 启动时加 numactl。Nginx 自身不支持 numa_bind 或 numa_interleave 配置项。
- 双路服务器(Node 0 和 Node 1)推荐分两组部署:
numactl --cpunodebind=0 --membind=0 /usr/sbin/nginx -g "daemon off;"numactl --cpunodebind=1 --membind=1 /usr/sbin/nginx -g "daemon off;" - systemd 用户,在
/etc/systemd/system/nginx.service.d/override.conf中重写ExecStart,避免被默认服务覆盖
worker_processes 数量必须与 NUMA 节点对齐
设成 auto 或总逻辑核数(如 32)是常见误区。真实有效的是按节点均分:
- Node 0 有 16 核 + 64GB 内存 → 建议
worker_processes 8–12(留出 2–4 核给中断、I/O、监控等) - Node 1 同理 → 总数建议设为 16,而非 32
- 若用
worker_cpu_affinity auto,仍需配合numactl;否则auto只在全系统范围内调度,完全无视 NUMA 边界
CPU 掩码顺序必须严格匹配内核编号
worker_cpu_affinity 0001 0010 0100 1000 中的每一位,对应 lscpu 或 cat /proc/cpuinfo 输出的 CPU 编号顺序。该顺序由物理插槽位置决定,不是简单按 0~N 排列。
- 错误配置会导致 worker 实际绑定到远端节点核心,性能反而下降
- 验证方法:
ps -eo pid,args,psr | grep 'nginx: worker'查 PSR 列是否稳定落在目标节点的 CPU 编号范围内(如 Node 0 对应 0–63)











