linux numa调优关键在于使内存分配、线程调度与硬件拓扑对齐:先用numactl --hardware和lscpu确认numa启用及拓扑,再通过numactl绑定cpu/内存节点、taskset固定线程、jvm参数或worker_cpu_affinity实现本地化访问,必要时微调vm.zone_reclaim_mode和kernel.numa_balancing。

Linux系统在NUMA(Non-Uniform Memory Access)架构下,内存访问延迟和带宽因CPU与内存节点的物理距离而异,不当的内存分配或进程绑定会显著拖慢性能。关键不是“禁用NUMA”,而是让内存分配、线程调度与硬件拓扑对齐。
看清当前NUMA拓扑
运行 numactl --hardware 查看节点数量、每个节点的CPU列表和内存容量;用 lscpu | grep -i numa 确认是否启用NUMA支持。注意:有些BIOS默认关闭NUMA,需手动开启才能生效。若显示单节点(Node 0 only),后续调优无从谈起。
避免跨节点内存分配
默认情况下,进程可能在任意节点分配内存,导致远端访问。可通过以下方式约束:
- 启动时指定节点:numactl --membind=1 --cpunodebind=1 ./app,强制进程只使用节点1的CPU和内存
- 对已有进程,用 numactl --interleave=all 可缓解内存不均(适合读多写少、对延迟不敏感的服务)
- 检查实际内存分布:numastat -p
,重点关注 numa_hit 与 numa_foreign 比值,foreign偏高说明频繁跨节点访问
绑定线程与本地内存节点
多线程应用(如数据库、Java服务)易因线程迁移引发远程内存访问。建议:
- 用 taskset -c 4-7 将线程固定到特定CPU核心,再配合 numactl --membind 绑定对应内存节点
- JVM可添加参数:-XX:+UseNUMA -XX:NUMAInterleavingRatio=1(JDK 8u262+),自动按节点划分堆内存
- Nginx/Apache等多worker模型,通过 worker_cpu_affinity auto 或脚本为每个worker绑定独立节点
内核参数微调(谨慎使用)
多数场景无需改内核参数,但以下两项在高并发内存密集型负载中值得验证:
- vm.zone_reclaim_mode=1:启用本地节点内存回收,减少跨节点分配(默认为0,即优先从其他节点分配)
- kernel.numa_balancing=0:关闭自动NUMA平衡(默认开启),避免后台线程迁移动态增加开销;适用于已手动绑定且负载稳定的场景
修改后需结合 numastat 和应用延迟指标对比验证,切勿盲目启用。











