NUMA Balancing 是 Linux 内核自带的自动 NUMA 优化机制 ,核心作用是:自动把进程迁移到它频繁访问的内存所在节点,同时把内存迁移到进程运行的节点,尽量让 "CPU 与内存同节点",减少跨 NUMA 节点访问延迟。
一、它解决什么问题?
没有 NUMA Balancing 时常见问题:
- 进程刚启动被调度到 Node0,但内存被分配在 Node1 → 全程跨节点访问,性能大幅下降。
- 线程被调度到其他 NUMA 节点,内存不跟着动 → 远程访问变多。
- 大内存应用(数据库、DPDK、Java 堆)内存分布散乱,跨节点访问严重。
NUMA Balancing 就是内核自动做亲和性,不用手动 numactl。
二、基本工作原理(极简流程)
- **页面错误陷阱(NUMA hint fault)**内核把部分内存页标记为 "不可访问"。
- 进程访问时触发缺页异常,内核记录访问来源节点。
- 内核统计:哪个节点的 CPU 在频繁访问这页内存。
- 动态迁移
- 内存页 → 迁移到进程所在节点
- 进程 / 线程 → 迁移到内存所在节点
- 周期性扫描、重新平衡
它是软机制,不强制绑定,会根据访问模式自动调整。
三、关键内核配置与开关
1. 查看是否开启
cat /proc/sys/kernel/numa_balancing
0= 关闭1= 开启(大多数现代发行版默认开启)
2. 临时开关
# 开启
echo 1 > /proc/sys/kernel/numa_balancing
# 关闭
echo 0 > /proc/sys/kernel/numa_balancing
3. 永久开启(sysctl)
kernel.numa_balancing = 1
四、相关可调参数(性能调优重点)
路径:/proc/sys/kernel/numa_balancing_*
numa_balancing_panic_threshold严重错误时是否 panic,一般默认即可。numa_balancing_scan_delay_ms扫描任务间隔,默认几百 ms。调大 → 开销低、反应慢调小 → 更敏感、CPU 开销高numa_balancing_scan_period_min_msnuma_balancing_scan_period_max_ms自动扫描周期的上下限。numa_balancing_scan_size_mb每次扫描多少 MB 内存页。
这些参数数据库、高性能计算场景经常微调。
五、NUMA Balancing 好处
- 自动优化,无需手动绑核、绑内存
- 对多线程、内存密集型应用提升明显
- 动态适应负载变化(进程迁移、流量变化)
- 对虚拟化、KVM vNUMA 也能协同工作
六、什么时候应该关闭 NUMA Balancing?
这是高频面试 / 运维考点:
必须关闭的场景
- DPDK、XDP、高性能网络平面用户态驱动自己管理内存,内核自动迁移会导致性能抖动、丢包。
- **数据库手动绑核(numactl 固定节点)**手动优化已经最优,内核乱动反而变差。
- **低时延要求业务(高频交易、实时系统)**页面扫描、迁移会带来毛刺延迟。
- 大页(HugePage)场景大页本身不易迁移,迁移成本极高,平衡机制效果差。
- 自己做了 CPU 亲和性、内存绑核的应用
简单记:手动 NUMA 优化越精细,越要关内核自动 NUMA Balancing。
七、如何观察 NUMA Balancing 效果
# 查看 NUMA 事件
numastat
# 持续观察
numastat -c 1
# 查看某个进程 NUMA 内存分布
numastat -p <pid>
重点看:
numa_hit:本地节点访问(越高越好)numa_miss:跨节点访问(越高越差)numa_foreign:内存分配在其他节点
开启 NUMA Balancing 后,正常情况 numa_hit 会上升。
八、与手动 numactl 的关系
- numactl --cpunodebind / --membind强绑定,优先级高于 NUMA Balancing。
- 内核不会把进程迁移出你绑定的节点。
- 但内存迁移仍可能发生,所以高性能场景一般直接关闭 numa_balancing。
九、总结一句话
NUMA Balancing 是内核自动让进程和内存就近配对 的机制,对普通应用提升明显、省心;但对DPDK、数据库、低时延业务,建议关闭,改用手动绑核绑内存。