You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Linux进程与模块的NUMA节点选择机制及Ubuntu 22.04节点0内存占用过高问题咨询

Linux进程与模块的NUMA节点选择机制及Ubuntu 22.04节点0内存占用过高问题咨询

嗨,这个问题挺常见的,我来给你拆解一下为什么默认情况下系统服务、二进制文件和关联库会扎堆在node0上,哪怕你没手动配置任何NUMA策略~

核心原因其实和系统启动流程、默认NUMA策略的继承性有关,具体可以分成这几点来看:

  • 内核与初始进程的启动节点绑定:系统启动时,BIOS/UEFI通常会把内核镜像加载到node0的内存区域中,后续启动的第一个用户态进程(Ubuntu 22.04里是systemd)会直接继承内核的NUMA亲和性——也就是默认运行在node0上。而所有系统服务都是systemd的子进程,自然也会继承这个节点偏好,优先在node0分配内存。
  • 系统二进制与库的缓存逻辑/bin/lib/usr这些目录下的系统二进制和库文件,在系统启动后会被内核缓存到内存中(也就是页缓存)。由于内核本身运行在node0,为了获取最快的访问速度,页缓存会优先分配到node0的内存里,这就进一步拉高了node0的内存占用。
  • 默认NUMA内存分配策略:Linux默认的内存分配策略是localalloc,简单说就是进程会优先从自己当前运行的NUMA节点申请内存。既然大部分系统服务都在node0运行,它们的内存自然也会优先落在node0上,形成“越用越多”的局面。
  • 无显式配置时的亲和性继承:如果没有通过numactltaskset或者systemd的NUMA配置项修改进程的节点偏好,所有进程都会继承父进程的NUMA亲和性。而整个系统的进程树最终都追溯到初始的systemd,所以几乎所有系统级进程都会默认绑定node0。

你可以用这些命令验证一下当前的状态:

  • 查看各NUMA节点的内存使用情况:numastat
  • 查看某个进程的NUMA节点绑定:ps -eo pid,cmd,numa_node | grep <进程名>
  • 查看系统默认的NUMA策略:numactl --show
  • 查看进程的CPU亲和性(间接对应NUMA节点):taskset -c <进程PID>

如果想平衡各节点的负载,你可以试试这些方法:

  • 对特定服务,用numactl指定启动时的NUMA节点,比如:numactl --cpunodebind=1 --membind=1 systemctl start <服务名>
  • 在systemd服务配置文件中添加NUMAPolicy=spread或者指定CPUAffinity,让服务分散到不同节点运行
  • 开启内核的NUMA自动平衡(默认可能已开启):echo 1 > /proc/sys/kernel/numa_balancing,不过这个对已经启动的进程效果有限,主要影响新启动的进程

备注:内容来源于stack exchange,提问作者Rama

火山引擎 最新活动