MongoDB/Mysql 如何以numactl 启动,开启 NUMA 以访问所有内存

  NUMA的含义,简单点说,在有多个物理CPU的架构下,NUMA把内存分为本地和远程,每个物理CPU都有属于自己的本地内存,访问本地内存速度快于访问远程内存,缺省情况下,每个物理CPU只能访问属于自己的本地内存。对于MongoDB这种需要大内存的服务来说就可能造成内存不足。需要使用numactl以使单颗CPU能访问所有内存。

  如果你是单颗CPU,或mongdo占用不会超过整体内存的一半,大概不需要此设置。有测试在mysql上,此项配置对性能影响约10%。

Ubuntu 安装 numactl

apt install numactl

使用 numactl 启动mongodb,以使 mongodb 每个线程可以访问所有的内存。

numactl --interleave=all /opt/app/mongodb/bin/mongod -f /etc/mongodb.conf

在 Ubuntu 的宝塔环境里,启动脚本为 /www/server/panel/plugin/mongodb/ mongodb_main.py 调用 /etc/init.d/mongodb 启动

修改 /etc/init.d/mongodb 中的以下行,可实现通过宝塔启动 。

sudo -u $User mongod -f $Config

修改为

sudo -u $User numactl --interleave=all mongod -f $Config

由于mysql多以mysqld_safe方式启动,不能直接修改 /etc/init.d/mysqld_safe,而修改 /usr/bin/mysqld_safe 脚本,在宝塔环境里,真实文件则在 /www/server/mysql/bin/mysqld_safe

/usr/bin/mysqld_safe约839-865行的 cmd="`mysqld_ld_preload_text`$NOHUP_NICENESS" 下面新增加一行。此配置会在升级或重装mysql时被重置,因此升级新版本后需要再修改一次。

cmd="`mysqld_ld_preload_text`$NOHUP_NICENESS"
# Add numactl --interleave=all 2023-8-18
cmd="numactl --interleave=all $cmd"

查看效果,如果 interleave_hit 变高,例如不再是几百的数值,则表示生效。

numastat -mn -p 'pid of mongod'
numastat -mn -p 'pid of mysqld'


numactl 常用命令

numactl --help

查看各节点 node 内存占用情况

numactl --hardware