在 CentOS 系统运维与高性能计算场景中,NUMA(NonUniform Memory Access,非统一内存访问)架构虽然能提升多处理器系统的内存访问并行度,但在运行特定类型的高负载应用(如 MySQL、Redis、Oracle 等数据库)时,往往会导致严重的性能衰减,核心上文归纳是:对于大多数单机多核数据库应用或对内存延迟敏感的高并发服务,在 CentOS 上彻底禁用 NUMA 架构是解决内存抖动、提升系统稳定性和响应速度的最有效手段,这通常通过修改内核启动参数(GRUB配置)来实现,将系统强制转换为 SMP(对称多处理)模式,从而消除跨 CPU 节点访问内存带来的延迟瓶颈。
深入理解为何需要禁用 NUMA
要掌握禁用 NUMA 的必要性,首先需理解其工作机制与潜在冲突,在 NUMA 架构下,物理内存被分割并分配给不同的 CPU 节点(Node),CPU 访问本地节点的内存速度快,访问远程节点的速度慢,操作系统调度器通常会尝试将进程调度在分配内存所在的节点上,以保持“内存亲和性”。

对于大型数据库应用,问题往往出在“内存交换”与“内存反弹”上,数据库通常会占用大量内存,甚至通过 mlock 锁定内存,当系统内存紧张时,Linux 的内存管理机制可能会尝试将某个 CPU 节点上的内存页面交换到 Swap 空间,即使其他 CPU 节点尚有充足的物理内存,这是因为内核无法有效地在 NUMA 节点间进行平衡的内存回收,这种不合理的内存交换会导致数据库性能急剧下降,若进程在 CPU A 上运行,但数据被分配在 CPU B 的内存上,就会产生频繁的跨节点访问,导致总线带宽拥堵,禁用 NUMA 后,操作系统将把所有内存视为单一连续的块,CPU 可以无差别地访问任意内存区域,从而规避了上述调度与分配的复杂性,对于无法自行感知 NUMA 拓扑的应用来说,性能反而更优。
检查当前系统的 NUMA 状态
在实施禁用操作前,必须确认当前硬件及系统的 NUMA 状态,这不仅能验证硬件是否支持 NUMA,还能为后续的优化效果提供对比基准。
最常用的检查工具是 numactl,若系统中未安装该工具,可通过 yum install numactl 进行安装,执行 numactl H 命令,输出结果将显示系统的节点数量、每个节点的 CPU 列表以及可用内存大小,如果显示的节点数大于 1,则说明系统当前处于 NUMA 模式,还可以通过 dmesg | grep i numa 查看内核启动日志中的 NUMA 相关信息,对于数据库服务器,如果发现多个节点且内存分布不均,通常意味着应用可能正遭受远程内存访问的延迟困扰。
彻底禁用 NUMA 的核心方案:修改 GRUB 内核参数
在生产环境中,最彻底、最专业的禁用 NUMA 的方法是修改内核启动参数,这种方法在系统启动时就生效,确保操作系统在初始化内存管理时即采用 SMP 模式。
操作步骤主要涉及编辑 /etc/default/grub 文件,在该文件中,找到 GRUB_CMdlINE_LINUX 这一行,该行定义了启动时传递给内核的参数,我们需要在该行引号内的参数列表中添加 numa=off,原配置可能为 GRUB_CMDLINE_LINUX="crashkernel=auto rd.lvm.lv=centos/root rd.lvm.lv=centos/swap rhgb quiet",修改后应变为 GRUB_CMDLINE_LINUX="crashkernel=auto rd.lvm.lv=centos/root rd.lvm.lv=centos/swap rh=gb quiet numa=off"。

修改完成后,对于 BIOS 启动的系统,需要运行 grub2mkconfig o /boot/grub2/grub.cfg 来生成新的 grub 配置文件;对于 UEFI 启动的系统,则通常使用 grub2mkconfig o /boot/efi/EFI/centos/grub.cfg,必须重启系统 reboot 才能使更改生效,重启后,再次运行 numactl H,若显示只有一个 Node,或者查看 /proc/cmdline 中包含 numa=off,即表示禁用成功。
针对特定应用的 NUMA 优化策略
虽然全局禁用 NUMA 能解决大多数数据库的痛点,但在某些混合负载环境中,我们可能不希望全局禁用,而是仅针对特定应用进行 NUMA 亲和性干预,这提供了更灵活的控制粒度。
如果不想全局禁用,可以使用 numactl 命令在启动应用时指定内存分配策略,最常用的参数是 interleave=all(或简写为 i all),该选项指示操作系统将内存页面交错分配到所有 CPU 节点上,而不是集中在某一个节点,这种方式可以有效防止单一节点内存耗尽导致的 Swap,同时平衡了各个节点的内存带宽压力,启动 MySQL 时可以使用如下命令:numactl interleave=all mysqld_safe defaultsfile=/etc/my.cnf &,这种方案无需重启系统,适合在不便停机的生产环境中进行临时调优,或者在虚拟化环境中对特定 Guest OS 进行优化。
验证与风险规避
实施 NUMA 禁用或调整后,必须进行严格的验证,通过 top 或 htop 观察 CPU 和内存的负载分布是否均衡,对于数据库,重点监控 QPS(每秒查询率)、TPS(每秒事务数)以及延迟指标,通常在禁用 NUMA 后,延迟的方差会显著减小,系统响应更加平稳。
禁用 NUMA 并非在所有场景下都是“银弹”,对于一些极其依赖大规模并行计算且能良好感知 NUMA 拓扑的科学计算应用(如某些 HPC 软件),禁用 NUMA 可能会导致内存总线争用加剧,反而降低性能,在通用 Web 服务器、文件服务器或未针对 NUMA 优化的老旧应用上,禁用 NUMA 是安全的;但在高性能计算领域,建议先进行压力测试对比,修改 GRUB 属于底层操作,务必在操作前备份配置文件,并确保具备救援模式下的恢复能力,以免配置错误导致系统无法启动。

相关问答
Q1:禁用 NUMA 后,服务器的内存性能一定会提升吗?A: 不一定,禁用 NUMA 主要解决的是内存分配不均和跨节点访问导致的延迟问题,对于单机多核数据库(如 MySQL、Oracle),通常能显著提升稳定性并减少 Swap,从而提升性能,但对于那些专门为 NUMA 架构编写、能够精确控制数据在哪个 CPU 节点内存分配的高性能计算(HPC)应用,禁用 NUMA 可能会失去并行内存访问的优势,导致性能下降,建议在禁用后进行 A/B 测试对比。
Q2:除了修改 GRUB 配置文件,还有其他临时禁用 NUMA 的方法吗?A: 有,如果不想重启系统或修改全局配置,可以使用 numactl 命令针对特定进程进行内存策略调整,最常用的方式是使用 numactl interleave=all 加上程序启动命令,这会将该进程的内存交错分布在所有 NUMA 节点上,模拟类似 UMA 的效果,某些硬件 BIOS 设置中也提供了关闭 NUMA 的选项,但这属于硬件层面的调整,效果与内核参数 numa=off 类似。
您在 CentOS 运维中是否遇到过因内存瓶颈导致的性能抖动?欢迎在评论区分享您的实际案例与解决方案。

