暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

NUMA介绍

原创 渔舟唱晚 2025-02-16
617

什么是 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 的优化复杂性

  • 手动调优困难:虽然可以通过 numactlnuma_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进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论