1. NUMA架构基础从对称多处理到非一致性内存访问第一次接触NUMA架构是在2015年调试一台八路服务器时。当时发现一个奇怪现象同样的程序在不同CPU核心上运行时性能差异能达到30%以上。这就是NUMA架构带来的典型特征——非均匀内存访问Non-Uniform Memory Access。传统SMP对称多处理架构中所有CPU通过共享总线访问内存。这种设计简单直观但随着CPU数量增加总线争用会形成性能瓶颈。我曾在实验室测试过当X86服务器CPU超过32核时内存带宽就会成为明显的性能瓶颈。而NUMA架构将系统划分为多个节点Node每个节点包含本地CPU组通常2-8个物理核心本地内存控制器可选I/O子系统关键区别在于访问路径本地内存访问通过节点内内存控制器直连延迟通常在80-100ns远程内存访问需要经过节点间互联如Intel QPI、AMD Infinity Fabric延迟可能达到200-300ns这种差异在数据库等内存敏感型应用中尤为明显。曾经有个MySQL案例当工作集超过本地节点内存容量时TPS直接下降40%。这就是为什么理解NUMA拓扑对性能调优至关重要。2. Linux中的NUMA拓扑发现与内存分配现代服务器启动时会通过ACPI表向OS报告NUMA拓扑。最重要的两张表是SRAT系统资源关联表记录CPU和内存的所属节点SLIT系统位置信息表记录节点间访问距离查看系统NUMA信息的实操命令# 查看节点布局 numactl --hardware # 查看CPU-内存关联 lstopo --of pdf topology.pdfLinux内存管理采用三级结构// 内核中的关键数据结构 typedef struct pglist_data { struct zone node_zones[MAX_NR_ZONES]; // 内存区域划分 struct zonelist node_zonelists[GFP_ZONEMASK1]; // 分配备用列表 int node_id; // 节点ID ... } pg_data_t;内存分配策略通过zonelist实现优先级控制。默认的分配顺序是当前节点ZONE_NORMAL相邻节点ZONE_NORMAL远程节点ZONE_NORMAL当前节点ZONE_HIGHMEM可以通过修改/proc/sys/vm/zone_reclaim_mode调整回收策略。在Oracle数据库服务器上我们通常会设置为1让内核更积极回收本地内存。3. NUMA调度器的核心机制Linux调度器经历了从O(1)到CFS的演进但NUMA感知的核心逻辑始终围绕两个关键点3.1 初始负载均衡进程创建时会分配一个home node选择算法如下def select_home_node(): min_load float(inf) candidate current_node for node in numa_nodes: load node.runnable_load node.memory_pressure if load min_load: min_load load candidate node return candidate实际项目中遇到过MySQL因home node选择不当导致的性能问题当mysqld进程被固定到内存紧张的节点时QPS波动达到25%。解决方案是用numactl显式绑定numactl --cpunodebind0 --membind0 mysqld_safe3.2 动态负载均衡调度器通过两个时间尺度进行平衡快速路径1ms周期处理当前节点的CPU间任务迁移慢速路径200ms周期跨节点负载均衡关键判断逻辑包括节点负载差异阈值默认25%内存局部性评分page迁移成本估算缓存热度考虑L3 cache命中率在KVM虚拟化环境中我们曾通过调整/sys/kernel/mm/numa_balancing参数获得15%的性能提升echo 1 /proc/sys/kernel/numa_balancing echo 10 /proc/sys/kernel/numa_balancing_delay_ms4. 实战调优数据库与虚拟化场景4.1 数据库工作负载优化以PostgreSQL为例需要关注以下参数# postgresql.conf shared_buffers 8GB # 不超过单个节点内存的70% effective_cache_size 24GB numa on # 启用NUMA感知分配关键操作步骤使用numastat监控跨节点访问watch -n 1 numastat -m通过pg_prewarm预热本地节点数据使用cgroup v2限制内存节点分布echo 0-1 /sys/fs/cgroup/mysql/cpuset.mems4.2 虚拟化环境配置在OpenStack环境中需要特别处理vCPU的固定!-- libvirt域配置 -- cputune vcpupin vcpu0 cpuset2/ vcpupin vcpu1 cpuset3/ numatune memory modestrict nodeset0/ /numatune /cputune常见问题排查工具链perf stat -e numa_migrationsqemu-monitor的info numa命令virt-top观察vCPU调度情况5. 高级调优技术与未来演进5.1 手动页迁移控制对于性能敏感型应用可以主动控制页迁移// 示例将页面移动到当前节点 move_pages(pid, page_count, pages, nodes, status, MPOL_MF_MOVE);5.2 AutoNUMA技术Linux 4.0引入的自动NUMA平衡机制包含页错误统计page fault accounting定期扫描线程kswapd NUMA基于机器学习预测的页面放置启用方式echo 1 /proc/sys/kernel/numa_balancing echo 50 /proc/sys/kernel/numa_balancing_rate_limit_mbps5.3 异构计算场景在搭载GPU的NUMA系统中需要注意PCIe拓扑与NUMA节点的对应关系GPU显存与主机内存的NUMA亲和性CUDA流处理器与CPU核心的绑定实测案例将TensorFlow进程绑定到靠近GPU的NUMA节点训练速度提升18%。