一、NUMA介绍
在介绍numactl之前,需要先说说NUMA是什么,这样才能更好的理解numactl。
NUMA(Non Uniform Memory Access Architecture)字面直译为"非一致性内存访问",对于Linux内核来说最早出现在2.6.7版本上。这种特性对于当下大内存+多CPU为潮流的X86平台来说确实会有不少的性能提升,但相反的,如果配置不当的话,也是一个很大的坑.
非统一内存访问(NUMA)是一种用于多处理器的电脑记忆体设计,内存访问时间取决于处理器的内存位置。 在NUMA下,处理器访问它自己的本地存储器的速度比非本地存储器(存储器的地方到另一个处理器之间共享的处理器或存储器)快一些。NUMA架构在逻辑上遵循对称多处理(SMP)架构。 它是在二十世纪九十年代被开发出来的,开发商包括Burruphs (优利系统), Convex Computer(惠普),意大利霍尼韦尔信息系统(HISI)的(后来的Group Bull),Silicon Graphics公司(后来的硅谷图形),Sequent电脑系统(后来的IBM),通用数据(EMC), Digital (后来的Compaq ,HP)。 这些公司研发的技术后来在类Unix操作系统中大放异彩,并在一定程度上运用到了Windows NT中。
首次商业化实现基于NUMA的Unix系统的是对称多处理XPS-100系列服务器,它是由VAST公司的Dan Gielen为HISI设计的。 这个架构的巨大成功使HISI成为了欧洲的顶级Unix厂商。
NUMA通过提供分离的存储器给各个处理器,避免当多个处理器访问同一个存储器产生的性能损失来试图解决这个问题。对于涉及到分散的数据的应用(在服务器和类似于服务器的应用中很常见),NUMA可以通过一个共享的存储器提高性能至n倍,而n大约是处理器(或者分离的存储器)的个数。
最早Intel在Nehalem架构上实现了NUMA,取代了在此之前一直使用的FSB前端总线的架构,用以对抗AMD的HyperTransport技术。一方面这个架构的特点是内存控制器从传统的北桥中移到了CPU中,排除了商业战略方向的考虑之外,这样做的方法同样是为了实现NUMA.
Intel的NUMA解决方案,Litrin始终认为它来自本家的安藤。他的模型有点类似于MapReduce。放弃总线的访问方式,将CPU划分到多个Node中,每个node有自己独立的内存空间。各个node之间通过高速互联通讯,通讯通道被成为QuickPath Interconnect即QPI。
二、如何判断一个多核机器(Linux)是否为NUMA结构
Redhat 或者Centos系统中可以通过如下命令:
grep -i numa /var/log/dmesg
查看输出结果,如果输出结果为:
No NUMA configuration found
说明numa为disable,如果不是上面的内容说明numa为enable
三、numactl介绍
numactl - Control NUMA policy for processes or shared memory #官方介绍
翻译:控制进程或共享内存的NUMA策略
Linux提供了一个手工调优的命令numactl(默认不安装,可以通过命令:yum install numactl来安装),首先你可以通过它查看系统的numa状态
[root@localhost yum.repos.d]# numactl --hardware
available: 2 nodes (0-1)
node 0 cpus: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 28 29 30 31 32 33 34 35 36 37 38 39 40 41
node 0 size: 65150 MB
node 0 free: 63334 MB
node 1 cpus: 14 15 16 17 18 19 20 21 22 23 24 25 26 27 42 43 44 45 46 47 48 49 50 51 52 53 54 55
node 1 size: 65503 MB
node 1 free: 63415 MB
node distances:
node 0 1
0: 10 21
1: 21 10
此系统共有2个node,各领取28个CPU和64G内存。
这里假设我要执行一个java param命令,此命令需要48G内存;一个python param命令,需要64G内存。
最好的优化方案时python在node0中执行,而java在node1中执行,那命令是:
#numactl --cpubind=0 --membind=0 python param
#numactl --cpubind=1 --membind=1 java param
当然,也可以自找没趣进行如下配置:
#numactl --cpubind=0 --membind=0,1 java param
通过numastat命令可以查看numa状态
注:numastat - Show per-NUMA-node memory statistics for processes and the operating system
中文翻译:显示进程和操作系统的每个NUMA节点内存统计信息
[root@localhost vm]# numastat
node0 node1
numa_hit 621608 1042558
numa_miss 0 0
numa_foreign 0 0
interleave_hit 36732 35731
local_node 619591 1005692
other_node 2017 36866
other_node过高意味着需要重新规划numa。
四、在NUMA硬件上部署MongoDB
在一个NUMA(Non-Uniform Access Memory)的系统上运行MongoDB会产生许多运维相关问题,包括间断性的慢查询和系统进程高负载使用。在一个NUMA硬件上部署MongoDB时,需要关闭NUMA,然后设置interleave内存策略。MongoDB 2.0以上版本在启动时会检测NUMA设置,并提示警告信息。
在Linux上部署MongoDB时,可以通过如下方法关闭NUMA
1、使用如下两个命令中的任意一个在sysctl设置中关闭zone reclaim
echo 0 | sudo tee /proc/sys/vm/zone_reclaim_mode
sudo sysctl -w vm.zone_reclaim_mode=0
2、使用numactl命令启动mongod实例(包括config servers、mongos),启动命令如下
numactl --interleave=all <path> <options>
举例:
numactl --interleave=all mongod -f /usr/local/mongodb/bin/rs3_member.conf
即分配所有的node供其使用,这也是官方推荐的用法。
在介绍numactl之前,需要先说说NUMA是什么,这样才能更好的理解numactl。
NUMA(Non Uniform Memory Access Architecture)字面直译为"非一致性内存访问",对于Linux内核来说最早出现在2.6.7版本上。这种特性对于当下大内存+多CPU为潮流的X86平台来说确实会有不少的性能提升,但相反的,如果配置不当的话,也是一个很大的坑.
非统一内存访问(NUMA)是一种用于多处理器的电脑记忆体设计,内存访问时间取决于处理器的内存位置。 在NUMA下,处理器访问它自己的本地存储器的速度比非本地存储器(存储器的地方到另一个处理器之间共享的处理器或存储器)快一些。NUMA架构在逻辑上遵循对称多处理(SMP)架构。 它是在二十世纪九十年代被开发出来的,开发商包括Burruphs (优利系统), Convex Computer(惠普),意大利霍尼韦尔信息系统(HISI)的(后来的Group Bull),Silicon Graphics公司(后来的硅谷图形),Sequent电脑系统(后来的IBM),通用数据(EMC), Digital (后来的Compaq ,HP)。 这些公司研发的技术后来在类Unix操作系统中大放异彩,并在一定程度上运用到了Windows NT中。
首次商业化实现基于NUMA的Unix系统的是对称多处理XPS-100系列服务器,它是由VAST公司的Dan Gielen为HISI设计的。 这个架构的巨大成功使HISI成为了欧洲的顶级Unix厂商。
NUMA通过提供分离的存储器给各个处理器,避免当多个处理器访问同一个存储器产生的性能损失来试图解决这个问题。对于涉及到分散的数据的应用(在服务器和类似于服务器的应用中很常见),NUMA可以通过一个共享的存储器提高性能至n倍,而n大约是处理器(或者分离的存储器)的个数。
最早Intel在Nehalem架构上实现了NUMA,取代了在此之前一直使用的FSB前端总线的架构,用以对抗AMD的HyperTransport技术。一方面这个架构的特点是内存控制器从传统的北桥中移到了CPU中,排除了商业战略方向的考虑之外,这样做的方法同样是为了实现NUMA.
Intel的NUMA解决方案,Litrin始终认为它来自本家的安藤。他的模型有点类似于MapReduce。放弃总线的访问方式,将CPU划分到多个Node中,每个node有自己独立的内存空间。各个node之间通过高速互联通讯,通讯通道被成为QuickPath Interconnect即QPI。
二、如何判断一个多核机器(Linux)是否为NUMA结构
Redhat 或者Centos系统中可以通过如下命令:
grep -i numa /var/log/dmesg
查看输出结果,如果输出结果为:
No NUMA configuration found
说明numa为disable,如果不是上面的内容说明numa为enable
三、numactl介绍
numactl - Control NUMA policy for processes or shared memory #官方介绍
翻译:控制进程或共享内存的NUMA策略
Linux提供了一个手工调优的命令numactl(默认不安装,可以通过命令:yum install numactl来安装),首先你可以通过它查看系统的numa状态
[root@localhost yum.repos.d]# numactl --hardware
available: 2 nodes (0-1)
node 0 cpus: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 28 29 30 31 32 33 34 35 36 37 38 39 40 41
node 0 size: 65150 MB
node 0 free: 63334 MB
node 1 cpus: 14 15 16 17 18 19 20 21 22 23 24 25 26 27 42 43 44 45 46 47 48 49 50 51 52 53 54 55
node 1 size: 65503 MB
node 1 free: 63415 MB
node distances:
node 0 1
0: 10 21
1: 21 10
此系统共有2个node,各领取28个CPU和64G内存。
这里假设我要执行一个java param命令,此命令需要48G内存;一个python param命令,需要64G内存。
最好的优化方案时python在node0中执行,而java在node1中执行,那命令是:
#numactl --cpubind=0 --membind=0 python param
#numactl --cpubind=1 --membind=1 java param
当然,也可以自找没趣进行如下配置:
#numactl --cpubind=0 --membind=0,1 java param
通过numastat命令可以查看numa状态
注:numastat - Show per-NUMA-node memory statistics for processes and the operating system
中文翻译:显示进程和操作系统的每个NUMA节点内存统计信息
[root@localhost vm]# numastat
node0 node1
numa_hit 621608 1042558
numa_miss 0 0
numa_foreign 0 0
interleave_hit 36732 35731
local_node 619591 1005692
other_node 2017 36866
other_node过高意味着需要重新规划numa。
四、在NUMA硬件上部署MongoDB
在一个NUMA(Non-Uniform Access Memory)的系统上运行MongoDB会产生许多运维相关问题,包括间断性的慢查询和系统进程高负载使用。在一个NUMA硬件上部署MongoDB时,需要关闭NUMA,然后设置interleave内存策略。MongoDB 2.0以上版本在启动时会检测NUMA设置,并提示警告信息。
在Linux上部署MongoDB时,可以通过如下方法关闭NUMA
1、使用如下两个命令中的任意一个在sysctl设置中关闭zone reclaim
echo 0 | sudo tee /proc/sys/vm/zone_reclaim_mode
sudo sysctl -w vm.zone_reclaim_mode=0
2、使用numactl命令启动mongod实例(包括config servers、mongos),启动命令如下
numactl --interleave=all <path> <options>
举例:
numactl --interleave=all mongod -f /usr/local/mongodb/bin/rs3_member.conf
即分配所有的node供其使用,这也是官方推荐的用法。