worker_processes auto更稳因它具备NUMA感知能力,能自动按本地内存节点均匀分发worker进程,避免跨节点访问导致的延迟翻倍与缓存命中率暴跌;手动设32核则易使部分进程运行在远端NUMA节点,引发CPU不均衡、numa_foreign升高及QPS异常下降。
worker_processes auto 为什么比手动设核数更稳
在双路或四路 NUMA 架构服务器上,手动写死
很可能让一半 worker 进程跑在远端 NUMA 节点上——它们访问内存要跨 QPI/UPI 总线,延迟翻倍,缓存命中率暴跌。而
从 Nginx 1.3.8 起就内置 NUMA 感知逻辑:它读取
下的节点拓扑,优先把 worker 进程均匀分发到每个本地内存节点对应的核心组,避免跨节点调度。
常见错误现象:
• 压测时 CPU 利用率不均衡(比如 32 核里只有 16 核跑满)
•
显示
低、
高
• 同样配置下,单路服务器 QPS 是双路的 1.8 倍以上
实操建议:
• 必须用
,不要手算总核数
• 验证是否生效:启动后执行
,观察各 worker 的 CPU 编号是否自然聚类(如 0–15 和 32–47 分两组)
• 若发现进程仍散落在所有逻辑 CPU 上,检查内核是否禁用了 NUMA(
)
worker_cpu_affinity auto 在 NUMA 场景下的真实行为
不是简单地按顺序绑核,而是配合
的 NUMA 分组结果,为每个 worker 自动分配同一 NUMA 节点内的连续核心。例如双路 32 核(每路 16 核),它会生成类似
的掩码(前 16 位和后 16 位分别对应两个节点)。
容易踩的坑:
• 手动写二进制掩码时错位(比如 32 核写成 32 位但实际有超线程,逻辑 CPU 数是 64)
• 在启用了 CPU 隔离(
)的系统上,
可能绑定到被隔离的核心,导致 worker 启动失败(报错
)
• Docker/K8s 环境中,容器未声明
,宿主机
会失效
实操建议:
• 先确认 NUMA 节点布局:
或
• 若需精细控制,改用显式掩码,但必须按节点分组写,例如双路 16c/32t:
• 容器部署时,
应与
保持一致
NUMA 感知调优必须同步调整的三个关联参数
只调
和
不够,NUMA 场景下这三个参数必须联动:
Nginx
在宝塔面板中轻松管理Nginx高性能Web服务器。提供可视化配置反向代理、负载均衡、SSL证书及HTTP缓存功能,一键优化高并发性能,助您高效搭建稳定、快速的网站运行环境。
下载
:每个 worker 进程打开的文件描述符上限,必须 ≥
× 1.2,否则高并发时触发
,且 NUMA 节点间 fd 表不共享,不能靠全局 ulimit 补救。
:启用后,每个 worker 在一次 epoll wait 中批量获取多个新连接,减少跨节点唤醒次数;关闭时,连接请求可能被不同节点的 worker 竞争,引发缓存抖动。
:零拷贝依赖 page cache 本地性,若文件页在远端 NUMA 节点,
反而比
更慢;必须配合
让内核主动迁移热页到本地节点。
性能影响:
• 未调
:QPS 卡在 3 万左右即触顶
•
:在 10 万连接压测中,
高出 40%
•
+ 无 NUMA 页迁移:静态文件响应延迟 P99 从 8ms 涨到 42ms
验证 NUMA 优化是否真正生效的三步法
别信配置文件写了就等于起效。真实生产环境必须走这三步:
• 第一步:确认 worker 进程物理分布
执行
,看 PID 是否按 CPU 编号自然分簇(如 PID 1234→CPU 0–15,PID 1235→CPU 32–47)
• 第二步:检查内存访问局部性
运行
,重点看
占比是否 >95%,
是否 other_node 持续增长,说明有跨节点内存分配
• 第三步:压测对比关键指标
用 wrk 或 go-wrk 对比开启 NUMA 优化前后:
– 同等 QPS 下的 CPU sys 时间(应下降 20%+)
– P99 延迟(应收窄且稳定)
–
中 cache-misses rate(应从 >8% 降至
最容易被忽略的是第三步里的
:它直接反映 CPU 缓存行在 NUMA 节点间的无效化频率,比任何吞吐数字都更能暴露底层亲和性缺陷。
worker_processes 32worker_processes auto/sys/devices/system/node/numastat -p $(pgrep nginx | head -1)numa_hitnuma_foreignworker_processes autops -eo pid,psr,comm | grep nginxcat /proc/cmdline | grep numa=offworker_cpu_affinity autoworker_processes autoworker_cpu_affinity 000000000000ffff 000000000000ffff0000000000000000isolcpusautobind() to 0.0.0.0:80 failed (98: Address already in use)--cpuset-cpusworker_cpu_affinitylscpu | grep "NUMA node"numactl --hardwareworker_processes 32; worker_cpu_affinity 0000000000000000000000000000ffff 0000000000000000ffff000000000000;worker_cpu_affinity--cpuset-cpusworker_processes autoworker_cpu_affinity autoworker_rlimit_nofileworker_connectionsaccept() failed (24: Too many open files)events { multi_accept on; }http { sendfile on; }sendfileread/writeecho 1 > /proc/sys/vm/numa_balancingworker_rlimit_nofilemulti_accept offcontext switches/secsendfile onps -eo pid,psr,comm | grep 'nginx: worker' | sort -k2nnumastat -p $(pgrep nginx | head -1)numa_hitnuma_foreignperf stat -e cycles,instructions,cache-misses -p $(pgrep nginx | head -1)cache-misses