NUMA,非统一内存访问(Non-uniform Memory Access),介于SMP(对称多处理)和MPP(大规模并行处理)之间,各个节点自有内存(甚至IO子系统),访问其它节点的内存则通过高速网络通道。NUMA信息主要通过BIOS中的ACPI(高级配置和编程接口)进行配置,Linux对NUMA系统的物理内存分布信息从系统firmware的ACPi表中获得,最重要的是SRAT(System Resource Affinity Table)和SLIT(System locality Information Table)表。SRAT表包含CPU信息、内存相关性信息,SLIT表则记录了各个节点之间的距离,在系统中由数组node_distance[]记录。这样系统可以就近分配内存,减少延迟。
Linux中用一个struct pg_data_t表示一个numa节点,Linux内核支持numa调度,并实现CPU的负载均衡。
既然提到了NUMA架构,那么我们就有必要先来了解下NUMA是什么。 NUMA,非统一内存访问(Non-uniform Memory Access),介于SMP和MPP之间。
在NUMA架构中,每一颗CPU被称为一个node,每个node之间的内存使用的独立的。首先我们来看下传统模式SMP的情况:
SMP架构:
我们可以看到,每个CPU之间是绝对平等的,没有优先级之分,访问内存都必须通过系统总线。同时CPU之间的访问也是需要经过系统总线的。
从这个架构大家也可以看到SMP架构的短板是什么地方了。 对于现在动辄数十个甚至几百个CPU的系统来讲,这显然是有问题的。系统的总线将是
整个系统的瓶颈。
因此随着技术的发展,引入了新的一种架构NUMA。 我们来看NUMA架构是什么样的:
NUMA架构:
大家从NUMA架构可以看出,每颗CPU之间是独立的,相互之间的内存是不影响的。每一颗CPU访问属于自己的内存,延迟是最小的。我们这里再混到前面的例子中:
查看是否支持:dmesg | grep -i numa
点击(此处)折叠或打开
-
[root@bj150 ~]# dmesg | grep -i numa
-
NUMA: Allocated memnodemap from b000 - b240
-
NUMA: Using 28 for the hash shift.
-
pci_bus 0000:00: on NUMA node 0 (pxm 1)
-
pci_bus 0000:40: on NUMA node 1 (pxm 2)
-
pci_bus 0000:3f: on NUMA node 0 (pxm 1)
- pci_bus 0000:7f: on NUMA node 1 (pxm 2)
要查看具体的numa信息用numastat
点击(此处)折叠或打开
-
[root@bj150 ~]# numastat
-
node0 node1
-
numa_hit 45239238685 13466502885
-
numa_miss 975259 1223334238
-
numa_foreign 1223334238 975259
-
interleave_hit 19791 19712
-
local_node 45239134585 13466488455
- other_node 1079359 1223348668
-
numa_hit是打算在该节点上分配内存,最后从这个节点分配的次数;
num_miss是打算在该节点分配内存,最后却从其他节点分配的次数;
num_foregin是打算在其他节点分配内存,最后却从这个节点分配的次数;
interleave_hit是采用interleave策略最后从该节点分配的次数;
local_node该节点上的进程在该节点上分配的次数
other_node是其他节点进程在该节点上分配的次数
lscpu可以看到两个node的cpu归属:
点击(此处)折叠或打开
-
[root@bj150 ~]# lscpu
-
Architecture: x86_64
-
CPU op-mode(s): 32-bit, 64-bit
-
Byte Order: Little Endian
-
CPU(s): 32
-
On-line CPU(s) list: 0-31
-
Thread(s) per core: 2
-
Core(s) per socket: 8
-
Socket(s): 2
-
NUMA node(s): 2
-
Vendor ID: GenuineIntel
-
CPU family: 6
-
Model: 62
-
Stepping: 4
-
CPU MHz: 2600.110
-
BogoMIPS: 5199.29
-
Virtualization: VT-x
-
L1d cache: 32K
-
L1i cache: 32K
-
L2 cache: 256K
-
L3 cache: 20480K
-
NUMA node0 CPU(s): 0,2,4,6,8,10,12,14,16,18,20,22,24,26,28,30
- NUMA node1 CPU(s): 1,3,5,7,9,11,13,15,17,19,21,23,25,27,29,31
-
。
-
各个cpu负载情况,使用命令:mpstat -P ALL(需要安装sysstat)
Linux上使用numactl设定进程的numa策略。常见的情况是,数据库daemon进程(mongodb,mysql)可能会吃掉很多内存,而一个numa节点上的内存很有限,内存不够时虚拟内存频繁与硬盘交换数据,导致性能急剧下降(标识是irqbalance进程或cpuspeed进程top中居高不下),这时应该采用interleave的numa策略,允许从其他节点分配内存。
查看每个节点对应的内存使用情况
-
[root@bj150 ~]# 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
-
[root@bj150 ~]# 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: 32722 MB
-
node 0 free: 11452 MB
-
node 1 cpus: 1 3 5 7 9 11 13 15 17 19 21 23 25 27 29 31
-
node 1 size: 32768 MB
-
node 1 free: 3877 MB
-
node distances:
-
node 0 1
-
0: 10 20
- 1: 20 10
禁用numa
1.在操作系统中关闭,可以直接在/etc/grub.conf的kernel行最后添加numa=off,如下所示:
kernel /vmlinuz-2.6.32-220.el6.x86_64 ro root=/dev/mapper/VolGroup-root rd_NO_LUKS LANG=en_US.UTF-8 rd_LVM_LV=VolGroup/root rd_NO_MD quiet SYSFONT=latarcyrheb-sun16 rhgb crashkernel=auto rd_LVM_LV=VolGroup/swap rhgb crashkernel=auto quiet KEYBOARDTYPE=pc KEYTABLE=us rd_NO_DM numa=off
2启动MySQL的时候,关闭NUMA特性:
numactl --interleave=all mysqldpath 这是使用交叉分配模式启动一个程序,也就是说程序可以随意跨节点用其他节点的内存,传说中这是效率最高的关闭NUMA特性的方法,只是传说。
或
numactl –cpunodebind=node –localalloc mysqld
3 BOIS层关闭
参考文档
http://blog.csdn.net/jollyjumper/article/details/17168175
http://www.tuicool.com/articles/FzmmQj