一、lscpu输出

使用lscpu查看的结果如下图,这里会显示很多信息,如下:

lscpu
lscpu

使用lscpu -p会详细的numa信息,如下:

 1[root@localhost ~]# lscpu  -p
 2# The following is the parsable format, which can be fed to other
 3# programs. Each different item in every column has an unique ID
 4# starting from zero.
 5# CPU,Core,Socket,Node,,L1d,L1i,L2,L3
 60,0,0,0,,0,0,0,0
 71,1,1,2,,1,1,1,1
 82,2,2,4,,2,2,2,2
 93,3,3,7,,3,3,3,3
104,0,0,0,,4,0,0,0
115,1,1,2,,5,1,1,1
126,2,2,4,,6,2,2,2
137,3,3,7,,7,3,3,3
148,4,0,0,,8,4,4,0
159,5,1,2,,9,5,5,4
16…………略部分

二、numa相关

1、numa架构及优势

目前,CPU主频速度和CPU的个数增长得很快。但是CPU访问内存的时候,速度依旧跟不上。虽然我们提出了L3 Cache这个概念,但并不能完全解决问题。CPU访问内存速度很慢,依然是我们的瓶颈。为了更好的解决这个问题,工业界引入了NUMA概念。架构如下:

numa
numa

上述结构中,我们有两个NUMA结点。每个NUMA结点有一些CPU, 一个内部总线,和自己的内存,甚至可以有自己的IO。每个CPU有离自己最近的内存可以直接访问。所以,使用NUMA架构,系统的性能会更快。在NUMA结构下,我们可以比较方便的增加CPU的数目。而在非NUMA架构下,增加CPU会导致系统总线负载很重,性能提升不明显。

这部分可以参考微软技术网站:https://blogs.msdn.microsoft.com/apgcdsd/2011/11/15/sql-servernuma/

2、numa缺点

numa可能造成的陷阱是:当你的服务器还有内存的时候,发现它已经在开始使用swap了,甚至已经导致机器出现停滞的现象。这个就有可能是由于numa的限制,如果一个进程限制它只能使用自己的numa节点的内存,那么当自身numa node内存使用光之后,就不会去使用其他numa node的内存了,会开始使用swap,甚至更糟的情况,机器没有设置swap的时候,可能会直接死机!所以你可以使用numactl –interleave=all来取消numa node的限制。

在不需要numa的环境中,可以在linux系统启动时,在kernel 项后面加上numa=Off来关闭numa特性。

3、numa的相关指令

Redhat或者Centos系统中可以通过命令判断bios层是否开启numa:

1# grep -i numa /var/log/dmesg

如果输出结果为: No NUMA configuration found 说明numa为disable,如果不是上面内容说明numa为enable,例如显示:NUMA: Using 30 for the hash shift. 可以通过lscpu命令查看机器的NUMA拓扑结构。

numa的主要控制包为numactl,可以通过yum -y install numactl 进行安装,安装完成后,可以通过如下命令查看:

 1[root@localhost ~]# numastat
 2                           node0           node1           node2           node3
 3numa_hit              6180519149      2927186074      6893389758       740766423
 4numa_miss                 106153         4777606         5260925        17027682
 5numa_foreign            18339060           71253         1163555         5716013
 6interleave_hit              8418            8545            8420            8539
 7local_node            6180506174      2927165336      6893369305       740751328
 8other_node                119128         4798344         5281378        17042777
 9                           node4           node5           node6           node7
10numa_hit              1820598189      2199393026      1949858949      2309669914
11numa_miss               20058925         5728700       105660553         1809681
12numa_foreign            18215922               0         1409936       115514486
13interleave_hit              8429            8530            8427            8535
14local_node            1820578507      2199373143      1949844296      2309649667
15other_node              20078607         5748583       105675206         1829928

当发现numa_miss数值比较高时,说明需要对分配策略进行调整。例如将指定进程关联绑定到指定的CPU上,从而提高内存命中率。numastat的输出等同于 cat /sys/devices/system/node/node0/numastat ,在/sys/devices/system/node/文件夹中记录系统中的所有内存节点的相关详细信息。

1# numactl --hardware  列举系统上的NUMA节点
2# numactl  --show   查看绑定信息

上面两个命令的具体输出类似如下:

 1[root@localhost ~]# numactl --hardware
 2available: 8 nodes (0-7)
 3node 0 cpus: 0 4 8 12 16 20
 4node 0 size: 16349 MB
 5node 0 free: 3889 MB
 6node 1 cpus: 24 28 32 36 40 44
 7node 1 size: 16384 MB
 8node 1 free: 3360 MB
 9node 2 cpus: 1 5 9 13 17 21
10node 2 size: 16384 MB
11node 2 free: 2043 MB
12node 3 cpus: 25 29 33 37 41 45
13node 3 size: 16384 MB
14node 3 free: 14478 MB
15node 4 cpus: 2 6 10 14 18 22
16node 4 size: 16384 MB
17node 4 free: 13789 MB
18node 5 cpus: 26 30 34 38 42 46
19node 5 size: 16384 MB
20node 5 free: 14668 MB
21node 6 cpus: 27 31 35 39 43 47
22node 6 size: 16384 MB
23node 6 free: 7845 MB
24node 7 cpus: 3 7 11 15 19 23
25node 7 size: 16367 MB
26node 7 free: 3804 MB
27node distances:
28node   0   1   2   3   4   5   6   7
29  0:  10  16  16  22  16  16  22  22
30  1:  16  10  16  22  22  22  16  22
31  2:  16  16  10  16  22  22  22  16
32  3:  22  22  16  10  22  16  22  16
33  4:  16  22  22  22  10  16  16  16
34  5:  16  22  22  16  16  10  22  22
35  6:  22  16  22  22  16  22  10  16
36  7:  22  22  16  16  16  22  16  10
37[root@localhost ~]# numactl  --show
38policy: default
39preferred node: current
40physcpubind: 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 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47
41cpubind: 0 1 2 3 4 5 6 7
42nodebind: 0 1 2 3 4 5 6 7
43membind: 0 1 2 3 4 5 6 7

这两个命令就列这么多,这两个命令还有一些参数,更多可以参考:Numa架构下进程与CPU绑定 ,在Linux系统层面,还有一个numad进程可以平衡cpu和内存之间的捆绑调用。该进程的作用类似于irqbalance。

4、numa小结

NUMA最大的特点是引入了node和distance的概念。对于CPU和内存这两种最宝贵的硬件资源,NUMA用近乎严格的方式划分了所属的资源组(node),而每个资源组内的CPU和内存是几乎相等。资源组的数量取决于物理CPU的个数(现有的PC server大多数有两个物理CPU,每个CPU有4个核);distance这个概念是用来定义各个node之间调用资源的开销,为资源调度优化算法提供数据支持。

每个进程(或线程)都会从父进程继承NUMA策略,并分配有一个优先node。如果NUMA策略允许的话,进程可以调用其他node上的资源;

NUMA的CPU分配策略有cpunodebind、physcpubind。cpunodebind规定进程运行在某几个node之上,而physcpubind可以更加精细地规定运行在哪些核上;

NUMA的内存分配策略有localalloc、preferred、membind、interleave。localalloc规定进程从当前node上请求分配内存;而preferred比较宽松地指定了一个推荐的node来获取内存,如果被推荐的node上没有足够内存,进程可以尝试别的node。membind可以指定若干个node,进程只能从这些指定的node上请求分配内存。interleave规定进程从指定的若干个node上以RR(Round Robin 轮询调度)算法交织地请求分配内存。

参考页面:NUMA的取舍与优化设置

三、chrt与进程调度

为了控制进程之间使用CPU的调用,系统层面有nice和renice命令用于控制进程之间的调用优先级,但这两个命令只是简单的为程序的用指定了优先级,系统层面同时引入了chrt命令,该命令的即可以查看或指定进程的优先级,也可以指定调度策略。可用的调度策略选项有:

1-f  --fifo  调度器设成 SCHED_FIFO
2-o  --other 调度器设成 SCHED_OTHER
3-r  --rr    调度器设成 SCHED_RR

具体用例如下:

 1查看进程468的调度策略:
 2# chrt -p 468
 3pid 468's current scheduling policy: SCHED_FIFO
 4pid 468's current scheduling priority: 85
 5将PID 1000 的进程设定成 SCHED_FIFO,优先级设定成50:
 6# chrt -f -p 50 1000
 7将PID 1000 的进程设定成 SCHED_OTHER,优先级设定成0:
 8# chrt -o -p 0 1000
 9起动 /bin/my-app 设定成 SCHED_FIFO,优先级设定成36:
10# chrt -f 36 /bin/my-app