NUMA体系结构详解 Non-Uniform Memory Access

一、商用服务器系统架构

从系统架构来看,目前的商用服务器大体可以分为三类,即对称多处理器结构(SMP:Symmetric Multi-Processor),非一致存储访问结构(NUMA:Non-Uniform Memory Access),以及海量并行处理结构(MPP:Massive Parallel Processing)。它们的特征分别描述如下:

SMP(Symmetric Multi-Processor)

所谓对称多处理器结构,是指服务器中多个CPU对称工作,无主次或从属关系。各CPU共享相同的物理内存,每个 CPU访问内存中的任何地址所需时间是相同的,因此SMP也被称为一致存储器访问结构(UMA:Uniform Memory Access)。对SMP服务器进行扩展的方式包括增加内存、使用更快的CPU、增加CPU、扩充I/O(槽口数与总线数)以及添加更多的外部设备(通常是磁盘存储)。

SMP服务器的主要特征是共享,系统中所有资源(CPU、内存、I/O等)都是共享的。也正是由于这种特征,导致了SMP服务器的主要问题,那就是它的扩展能力非常有限。对于SMP服务器而言,每一个共享的环节都可能造成SMP服务器扩展时的瓶颈,而最受限制的则是内存。由于每个CPU必须通过相同的内存总线访问相同的内存资源,因此随着CPU数量的增加,内存访问冲突将迅速增加,最终会造成CPU资源的浪费,使 CPU性能的有效性大大降低。实验证明,SMP服务器CPU利用率最好的情况是2至4个CPU。           

 

图1.SMP服务器CPU利用率状态

NUMA(Non-Uniform Memory Access)

由于SMP在扩展能力上的限制,人们开始探究如何进行有效地扩展从而构建大型系统的技术,NUMA就是这种努力下的结果之一。利用NUMA技术,可以把几十个CPU(甚至上百个CPU)组合在一个服务器内。其CPU模块结构如图2所示: 

 

图2.NUMA服务器CPU模块结构

NUMA服务器的基本特征是具有多个CPU模块,每个CPU模块由多个CPU(如4个)组成,并且具有独立的本地内存、I/O槽口等。由于其节点之间可以通过互联模块(如称为Crossbar Switch)进行连接和信息交互,因此每个CPU可以访问整个系统的内存(这是NUMA系统与MPP系统的重要差别)。显然,访问本地内存的速度将远远高于访问远地内存(系统内其它节点的内存)的速度,这也是非一致存储访问NUMA的由来。由于这个特点,为了更好地发挥系统性能,开发应用程序时需要尽量减少不同CPU模块之间的信息交互。利用NUMA技术,可以较好地解决原来SMP系统的扩展问题,在一个物理服务器内可以支持上百个CPU。比较典型的NUMA服务器的例子包括HP的Superdome、SUN15K、IBMp690等。

但NUMA技术同样有一定缺陷,由于访问远地内存的延时远远超过本地内存,因此当CPU数量增加时,系统性能无法线性增加。如HP公司发布Superdome服务器时,曾公布了它与HP其它UNIX服务器的相对性能值,结果发现,64路CPU的Superdome (NUMA结构)的相对性能值是20,而8路N4000(共享的SMP结构)的相对性能值是6.3。从这个结果可以看到,8倍数量的CPU换来的只是3倍性能的提升。 

 

在NUMA中还有三个节点的概念:

1)、本地节点:对于某个节点中的所有CPU,此节点称为本地节点。

2)、邻居节点:与本地节点相邻的节点称为邻居节点。

3)、远端节点:非本地节点或邻居节点的节点,称为远端节点。

4)、邻居节点和远端节点,都称作非本地节点(Off Node)。

CPU访问不同类型节点内存的速度是不相同的,访问本地节点的速度最快,访问远端节点的速度最慢,即访问速度与节点的距离有关,距离越远访问速度越慢,此距离称作Node Distance。应用程序要尽量的减少不通CPU模块之间的交互,如果应用程序能有方法固定在一个CPU模块里,那么应用的性能将会有很大的提升。
 

图3.MPP服务器架构图

MPP(Massive Parallel Processing)

和NUMA不同,MPP提供了另外一种进行系统扩展的方式,它由多个SMP服务器通过一定的节点互联网络进行连接,协同工作,完成相同的任务,从用户的角度来看是一个服务器系统。其基本特征是由多个SMP服务器(每个SMP服务器称节点)通过节点互联网络连接而成,每个节点只访问自己的本地资源(内存、存储等),是一种完全无共享(Share Nothing)结构,因而扩展能力最好,理论上其扩展无限制,目前的技术可实现512个节点互联,数千个CPU。目前业界对节点互联网络暂无标准,如 NCR的Bynet,IBM的SPSwitch,它们都采用了不同的内部实现机制。但节点互联网仅供MPP服务器内部使用,对用户而言是透明的。

在MPP系统中,每个SMP节点也可以运行自己的操作系统、数据库等。但和NUMA不同的是,它不存在异地内存访问的问题。换言之,每个节点内的CPU不能访问另一个节点的内存。节点之间的信息交互是通过节点互联网络实现的,这个过程一般称为数据重分配(Data Redistribution)。

但是MPP服务器需要一种复杂的机制来调度和平衡各个节点的负载和并行处理过程。目前一些基于MPP技术的服务器往往通过系统级软件(如数据库)来屏蔽这种复杂性。举例来说,NCR的Teradata就是基于MPP技术的一个关系数据库软件,基于此数据库来开发应用时,不管后台服务器由多少个节点组成,开发人员所面对的都是同一个数据库系统,而不需要考虑如何调度其中某几个节点的负载。

NUMA与MPP的区别

从架构来看,NUMA与MPP具有许多相似之处:它们都由多个节点组成,每个节点都具有自己的CPU、内存、I/O,节点之间都可以通过节点互联机制进行信息交互。那么它们的区别在哪里?通过分析下面NUMA和MPP服务器的内部架构和工作原理不难发现其差异所在。

首先是节点互联机制不同,NUMA的节点互联机制是在同一个物理服务器内部实现的,当某个CPU需要进行远地内存访问时,它必须等待,这也是NUMA服务器无法实现CPU增加时性能线性扩展的主要原因。而MPP的节点互联机制是在不同的SMP服务器外部通过I/O 实现的,每个节点只访问本地内存和存储,节点之间的信息交互与节点本身的处理是并行进行的。因此MPP在增加节点时性能基本上可以实现线性扩展。

其次是内存访问机制不同。在NUMA服务器内部,任何一个CPU可以访问整个系统的内存,但远地访问的性能远远低于本地内存访问,因此在开发应用程序时应该尽量避免远地内存访问。在MPP服务器中,每个节点只访问本地内存,不存在远地内存访问的问题。

 

二、NUMA实践

1、安装numactl工具
Linux提供了一个一个手工调优的命令numactl(默认不安装)

#yum install numactl -y

 

#numactl --hardware  列举系统上的NUMA节点


2、查看numa状态

# numactl  --show
policy: default
preferred node: current
physcpubind: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
cpubind: 0 1
nodebind: 0 1
membind: 0 1

 

# numastat
                           node0           node1
numa_hit              1296554257       918018444
numa_miss                8541758        40297198
numa_foreign            40288595         8550361
interleave_hit             45651           45918
local_node            1231897031       835344122
other_node              64657226        82674322



说明:

numa_hit—命中的,也就是为这个节点成功分配本地内存访问的内存大小

numa_miss—把内存访问分配到另一个node节点的内存大小,这个值和另一个node的numa_foreign相对应。

numa_foreign–另一个Node访问我的内存大小,与对方node的numa_miss相对应

local_node----这个节点的进程成功在这个节点上分配内存访问的大小

other_node----这个节点的进程 在其它节点上分配的内存访问大小

很明显,miss值和foreign值越高,就要考虑绑定的问题。

3、numad服务

在redhat6中,有一个numad的服务(需手工安装),它可以自动的监控我们cpu状况,并自动平衡资源,这个服务需要在内存使用量非常大的时候才会有明显的效果,当内存空余量较大时,需要关闭KSM,避免发生冲突。官方说在某些内存使用巨大的环境中,可能会提高50%的性能。

# service numad start



4、查看cpu和内存使用情况

# numactl --hardware
available: 2 nodes (0-1)
node 0 cpus: 0 2 4 6 8 10 12 14 16 18 20 22 24 26 28 30
node 0 size: 64337 MB
node 0 free: 1263 MB
node 1 cpus: 1 3 5 7 9 11 13 15 17 19 21 23 25 27 29 31
node 1 size: 64509 MB
node 1 free: 30530 MB
node distances:
node   0   1
  0:  10  21
  1:  21  10


cpu0 可用 内存 1263 MB

cpu1 可用内存 30530 MB

当cpu0上申请内存超过1263M时必定使用swap,这个是很不合理的。

这里假设我要执行一个java param命令,此命令需要1G内存;一个python param命令,需要8G内存。
最好的优化方案时python在node1中执行,而java在node0中执行,那命令是:

#numactl --cpubind=0 --membind=0 python param
#numactl --cpubind=1 --membind=1 java param


5、NUMA的内存分配策略

1.缺省(default):总是在本地节点分配(分配在当前进程运行的节点上);

2.绑定(bind):强制分配到指定节点上;

3.交叉(interleave):在所有节点或者指定的节点上交织分配;

4.优先(preferred):在指定节点上分配,失败则在其他节点上分配。

因为NUMA默认的内存分配策略是优先在进程所在CPU的本地内存中分配,会导致CPU节点之间内存分配不均衡,当某个CPU节点的内存不足时,会导致swap产生,而不是从远程节点分配内存。这就是所谓的swap insanity 现象。

举例:

# numactl --hardware
node 0 cpus: 0 2 4 6
node 0 size: 65490 MB
node 0 free: 24447 MB
node 1 cpus: 1 3 5 7
node 1 size: 65536 MB
node 1 free: 16050 MB
node distances:
node   0   1
  0:  10  20
  1:  20  10


可以看到numa节点是2个,cpu物理节点是8个
现在我们绑定资源,两颗cpu,每颗4个物理节点,那么我们开4个mysql实例,每个实例绑定2个cpu物理节点

numactl --physcpubind=0,3 --localalloc  mysqld_multi --defaults-extra-file=/etc/mysqld_multi.cnf start 1


–physcpubind 指定绑定的cpu节点,

–localalloc表示使用内存方式,不交叉,以免降低性能,

mysqld_multi是mysql实例启动命令

三、如何关闭NUMA

方法一:通过bios关闭

BIOS:interleave = Disable / Enable

方法二:通过OS关闭

1、编辑 /etc/default/grub 文件,加上:numa=off

GRUB_CMDLINE_LINUX="crashkernel=auto numa=off rd.lvm.lv=centos/root rd.lvm.lv=centos/swap rhgb quiet"

2、重新生成 /etc/grub2.cfg 配置文件:

# grub2-mkconfig -o /etc/grub2.cfg

3、重启操作系统

# reboot

4、确认:

# dmesg | grep -i numa
[    0.000000] Command line: BOOT_IMAGE=/vmlinuz-3.10.0-327.el7.x86_64 root=/dev/mapper/centos-root ro crashkernel=auto numa=off rd.lvm.lv=centos/root rd.lvm.lv=centos/swap rhgb quiet[    0.000000] NUMA turned off[    0.000000] Kernel command line: BOOT_IMAGE=/vmlinuz-3.10.0-327.el7.x86_64 root=/dev/mapper/centos-root ro crashkernel=auto numa=off rd.lvm.lv=centos/root rd.lvm.lv=centos/swap rhgb quiet

# cat /proc/cmdline
BOOT_IMAGE=/vmlinuz-3.10.0-327.el7.x86_64 root=/dev/mapper/centos-root ro crashkernel=a

参考

NUMA Best Practices for Dell PowerEdge 12th Generation Servers

https://blog.csdn.net/blackmanren/article/details/53490655

http://cenalulu.github.io/linux/numa/

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值