什么是 NUMA?
NUMA(Non-Uniform Memory Access,非统一内存访问) 是一种针对多处理器系统的内存架构设计。在传统的 UMA(Uniform Memory Access,统一内存访问) 架构中,所有 CPU 核心通过共享总线访问内存,内存访问延迟对所有核心是相同的。而 NUMA 将多个 CPU 和内存划分为多个 NUMA 节点(Node),每个节点内的 CPU 访问本地内存(Local Memory)速度较快,而访问其他节点的内存(Remote Memory)需要通过互联总线,延迟较高。
例如:
- 一个服务器有 2 个 NUMA 节点(Node 0 和 Node 1),每个节点包含若干 CPU 核心和本地内存。
- Node 0 的 CPU 访问 Node 0 的内存速度快,但访问 Node 1 的内存速度较慢。
为什么数据库服务器建议关闭 NUMA?
数据库服务器(如 MySQL、PostgreSQL、Oracle 等)通常需要高效、连续地管理大量内存(如缓冲池、缓存等),而 NUMA 的以下特性可能导致性能问题:
1. 内存分配不均衡
- 默认策略:Linux 的 NUMA 内存分配策略倾向于优先从**本地节点(Local Node)**分配内存。如果数据库进程(如 MySQL)绑定在某个 NUMA 节点上,可能导致该节点的内存被快速耗尽,而其他节点的内存闲置。
- 问题:当本地节点内存不足时,系统可能触发以下行为:
- 使用 Swap:即使其他节点有可用内存,仍可能将本地内存页换出到磁盘,导致性能急剧下降(称为 Swap Insanity)。
- 跨节点访问:频繁访问远程内存会增加延迟,降低吞吐量。
2. 数据库的工作负载特点
- 高并发、大内存需求:数据库需要高效管理大量数据缓存(如 InnoDB Buffer Pool),若内存分配受限于单个 NUMA 节点,可能无法充分利用全部内存资源。
- 内存局部性差:数据库进程可能被调度到不同 NUMA 节点的 CPU 上,导致内存访问模式难以预测,增加远程访问比例。
3. NUMA 的优化复杂性
- 手动调优困难:虽然可以通过
numactl或numa_maps工具手动绑定进程和内存分配,但对于动态负载的数据库来说,维护成本高且容易出错。 - 自动策略不足:操作系统默认的 NUMA 平衡策略(如
kernel.numa_balancing)可能无法满足数据库对低延迟和高吞吐的需求。
解决方案:禁用或优化 NUMA
1. 关闭 NUMA(不推荐)
- BIOS 设置:在服务器 BIOS 中禁用 NUMA(部分硬件支持将其转换为 UMA 模式)。
- 内核参数:在 Linux 内核启动参数中添加
numa=off,强制禁用 NUMA 支持。
2. 优化 NUMA 策略(推荐)
- 内存交错分配:使用
numactl --interleave=all启动数据库进程,允许内存从所有 NUMA 节点交错分配,避免局部内存耗尽。numactl --interleave=all mysqld ... - 调整内核参数:在
/etc/sysctl.conf中设置:vm.zone_reclaim_mode = 0 # 禁用内存区域回收(避免触发 Swap) kernel.numa_balancing = 0 # 关闭自动 NUMA 平衡(部分场景有效) - 绑定进程到特定节点:对于多实例数据库,可将不同实例绑定到不同 NUMA 节点,隔离资源。
现代改进
- 数据库优化:新版数据库(如 MySQL 8.0+)已支持 NUMA 感知的内存分配策略。
- 操作系统优化:Linux 内核(5.x+)改进了 NUMA 平衡算法,减少 Swap 触发概率。
总结
- NUMA 的初衷是提升多路服务器的扩展性,但数据库的高内存需求与默认的本地内存分配策略存在冲突。
- 建议:在内存密集型数据库场景中,优先使用
interleave=all策略,而非完全禁用 NUMA。若性能问题仍然存在,再考虑关闭 NUMA。
「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。




