专用服务器的 NUMA 感知与 CPU 绑定

16 分钟阅读 - 2026年6月16日

hero section cover
目录
  • 专用服务器的 NUMA 感知与 CPU 绑定
  • NUMA 在多插槽服务器上的工作原理
  • 在 Linux 上检查 NUMA 拓扑
  • CPU 绑定与内存策略
  • 根据工作负载选择策略
  • 需检查的 BIOS 和内核设置
分享

如何检查 NUMA 拓扑结构,并将 Linux 工作负载分配到正确的核心和内存上。内容涵盖 numactl、taskset、systemd、BIOS 设置以及针对特定工作负载的策略。

专用服务器的 NUMA 感知与 CPU 绑定

在任何多插槽服务器上,进程的运行位置与其内存驻留位置是两个不同的问题,而让二者失调是导致性能浪费的最常见原因之一。 NUMA 感知与 CPU 固定正是解决这一问题的两大关键手段。本文将介绍 NUMA 的工作原理、如何在 Linux 上进行检测,以及如何为数据库、AI 训练和对延迟敏感的服务正确地固定工作负载。

NUMA 在多插槽服务器上的工作原理

NUMA(非统一内存访问)节点是一组通过专用内存控制器绑定到本地 RAM 块的 CPU 核心。在双插槽服务器上,通常有两个节点。 任何核心均可读取任意地址,但本地访问延迟约为 80 纳秒,而通过英特尔 UPI 或 AMD Infinity Fabric 进行跨插槽传输的延迟则在 130–150 纳秒左右。在插槽数量更多的大型系统中,最差情况下的节点延迟可能超过 250 纳秒。

带宽表现遵循相同规律。双插槽 Sapphire Rapids 系统在核心访问本地内存时可维持约 600 GB/s 的带宽,但插槽间链路的带宽仅为其一小部分,因此跨插槽传输很快就会成为瓶颈。 高核心数处理器使这一问题更加细化:英特尔的 Sub-NUMA 集群 (SNC) 和 AMD 的每插槽节点数 (NPS) 将每个插槽划分为多个 NUMA 域,因此一台“双插槽”机器可以轻松向 Linux 呈现四个或八个节点。

如果缺乏对 NUMA 的感知,Linux 调度器会毫不犹豫地在插槽之间迁移线程,而其工作集却仍保留在原始节点上。此后每次访问都变成了远程访问。其明显症状是 CPU 利用率高而实际吞吐量低,因为核心一直在等待内存响应。I/O 设备会使情况更加恶化。 GPU 或 NIC 连接到特定的 PCIe 根总线,该总线属于某个 NUMA 节点。如果为其提供数据的进程运行在另一个插槽上,每次 DMA 传输都必须穿越互连总线。

在 Linux 上检查 NUMA 拓扑

以下四种工具几乎涵盖了您所需的一切:

  • lscpu 用于快速查看套接字和节点摘要。
  • numactl --hardware 用于查看节点内存总量及节点间距离矩阵。
  • numastat 用于查看每个进程的命中/未命中计数器。
  • lstopo (来自 hwloc)用于缓存层次结构和 PCIe 设备局部性分析。

numactl --hardware。该文件列出了每个节点、其所属的核心和内存,以及距离矩阵。数值为10表示本地,20+表示远程。若在多插槽服务器上仅看到单个节点,说明您的BIOS启用了节点交错(Node Interleaving)并隐藏了拓扑结构,请先解决此问题(见下文)。

对于特定进程, numastat -p <PID> 会详细显示其内存的实际分配位置。有四个计数器值得关注:

  • numa_hit:在目标节点上分配的内存。该值应尽可能高。
  • numa_miss:目标节点已满,分配溢出至其他节点。
  • numa_foreign:其他节点尝试本地分配但未成功,表明存在内存压力。
  • other_node: 在进程运行节点以外的节点上分配的页面。此处的数值过高是固定策略不佳的典型迹象。

对于 GPU 或 NIC 工作负载,请运行 lstopo-no-graphics 并查看每个 PCIe 设备连接到了哪个 NUMA 节点。如果驱动该设备的内核位于另一个节点上,这便是首要解决的问题。

CPU 绑定与内存策略

CPU 固定(或称 CPU 亲和性)将进程绑定到特定核心,从而防止调度器将其迁移。仅靠这一点还不够,因为 Linux 默认采用首次写入内存策略:内存页会被分配到第一个对其进行写入操作的节点上。 如果一个线程在被固定之前在错误的节点上启动,其内存就会保留在那里。您需要同时控制放置和分配。

有三种工具可处理常见情况:

工具控制功能适用场景
taskset仅限 CPU 核心快速对现有进程进行一次性绑定
numactlCPU 核心和内存启动具有严格局部性的工作负载
systemdCPU 核心和内存,持久化需要在重启后保持固定的服务

numactl 支持四种内存策略:

  • --membind=N:仅在节点 N 上分配,若已满则失败。
  • --preferred=N: 优先使用节点 N,必要时回退到其他节点。
  • --interleave=all:在节点间轮询分配,以实现带宽均衡。
  • --localalloc:在运行该工作负载的 CPU 所在的节点上分配。

将工作负载固定到某个节点

首先,确定哪些核心属于目标节点:

numactl --hardware

然后启动应用程序,使其在核心和内存上都绑定到该节点:

numactl --cpunodebind=0 --membind=0 ./your_application

对于已运行的进程,使用 taskset:

taskset -cp 0-7 <PID>

若要使其在重启后生效,请在 systemd 单元中进行设置:

[Service]
CPUAffinity=0-7
NUMAPolicy=bind
NUMAMask=0

重新加载并重启:

sudo systemctl daemon-reload && sudo systemctl restart <service>

当您手动绑定时,请关闭内核的自动负载均衡功能,以免其干扰您的资源分配:

sysctl -w kernel.numa_balancing=0

将其添加到 /etc/sysctl.conf 中以实现持久化。随后通过 numastat -p <PID> 在几分钟的实际工作负载下进行验证。如果 other_node 始终保持在零附近,则说明固定配置已生效。

根据工作负载选择策略

正确的策略取决于您的工作负载是更受益于低延迟,还是更受益于所有节点间的总带宽。

工作负载策略原因
数据库(PostgreSQL、MySQL、SQL Server)--cpunodebind + --membind大型共享缓冲区、对延迟敏感的查询路径
内存缓存(Redis、Memcached)单节点绑定所有操作均访问内存,远程延迟会立即显现
AI/ML 训练与推理绑定至 GPU 的 NUMA 节点避免张量传输跨越 PCIe 根节点
分析(SparkElasticsearch--interleave=all大型工作集需要跨所有节点的带宽
对延迟敏感的API,权衡取舍严格的固定 + IRQ 亲和性可预测性比峰值吞吐量更重要
网络密集型(RoCEv2、InfiniBand将引脚绑定至网卡的 NUMA 节点,为中断分配专用核心将中断处理保持在本地,避免干扰应用线程

针对 GPU 工作负载,请运行 lstopo 以确定 GPU 所在的 NUMA 节点,随后使用 numactl --cpunodebind=N --membind=N 针对该 N 启动训练或推理进程。这是在多插槽 GPU 服务器上最容易获得收益的方法之一,因为默认调度程序的放置通常是错误的。

对于横跨两个插槽的 HPC 和 MPI 工作负载,请使用 localalloc 将每个 rank 固定在单个节点上,而不是将所有任务交错分配。每个 rank 都将获得本地内存,并行处理将在 rank 级别进行。

一个实用提示:若将任务固定在单个节点上,请在该节点上预留 2–4 GB 的内存空间。若节点运行接近满载,将触发内存回收机制,这会消耗掉您原本试图节省的延迟。

需检查的 BIOS 和内核设置

工具输出的准确性取决于固件所呈现的拓扑结构。需确认以下几项设置:

  • 节点交错Node Interleaving):请将其禁用。启用该功能时,BIOS 会将所有内存呈现为单一的扁平化内存池,并完全向操作系统隐藏 NUMA 信息。 numactl --hardware 若启用此功能,多插槽服务器上将仅显示一个节点。
  • 子 NUMA 集群(Intel)或每插槽节点数(AMD):若需更精细的局部性,请在高核心数处理器上启用。重启后 lscpu 重启后进行确认。
  • vm.zone_reclaim_mode:对于大多数生产服务器,请设置为 0。非零值会激进地回收本地内存而非远程分配,这可能导致有用的页面缓存被驱逐。
  • kernel.numa_balancing:通用工作负载下保持启用,手动固定时关闭。自动平衡器迁移页面和线程的方式可能与您的策略冲突。

若您在裸机环境中进行 NUMA 调优(可控制 BIOS、内核参数及 IRQ 亲和性),则无需绕过虚拟机管理程序的抽象层即可应用上述所有设置。这正是此类工作在专用硬件上比在云虚拟机中更易实现的主要原因。

对于具有完全 root 访问权限的多插槽专用服务器,请参阅 FDC 的专用服务器

博客

本周特色

更多文章
优化 Linux 服务器工作负载的调整配置文件

优化 Linux 服务器工作负载的调整配置文件

如何为 GPU、数据库和高带宽 Linux 服务器选择、应用和定制经过调整的配置文件,并提供示例和 Ansible 部署技巧。

16 分钟阅读 - 2026年6月9日

VPS 的 Linux OOM 杀手调整:实用指南

12 分钟阅读 - 2026年6月8日

更多文章