numa网卡绑定
# 概念
参考:https://www.jianshu.com/p/0f3b39a125eb (opens new window)
chip:芯片,一个cpu芯片上可以包含多个cpu core,比如四核,表示一个chip里4个core。
socket:芯片插槽,颗,跟上面的chip一样。两颗四核,就表示总共8个core
core:包含在一个cpu芯片里的多个核心
LCPU:逻辑cpu,一个core里可以做多个逻辑cpu,每个LCPU只有寄存器,没有计算单元,类似于分时复用,就是人们常说的线程。4核8线程,就是4个core,一个core里两个线程。
下图为一个四核八线程的chip:
# numastat查看当前numa状态:
$ 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
12345678
# 说明:
numa_hit—命中的,也就是为这个节点成功分配本地内存访问的内存大小
numa_miss—把内存访问分配到另一个node节点的内存大小,这个值和另一个node的numa_foreign相对应。
numa_foreign–另一个Node访问我的内存大小,与对方node的numa_miss相对应
local_node----这个节点的进程成功在这个节点上分配内存访问的大小
other_node----这个节点的进程 在其它节点上分配的内存访问大小
很明显,miss值和foreign值越高,就要考虑绑定的问题。
# 查看某个进程的numa内存分配情况
$ numastat -p 39862
Per-node process memory usage (in MBs) for PID 1860 (yd_ex1)
Node 0 Node 1 Total
--------------- --------------- ---------------
Huge 0.00 0.00 0.00
Heap 0.02 0.00 0.02
Stack 0.02 0.00 0.02
Private 1.55 0.10 1.65
---------------- --------------- --------------- ---------------
Total 1.59 0.10 1.69
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
# 查看numa节点的cpu分配
# $ numactl --hardware
$ numactl -H
available: 2 nodes (0-1)
node 0 cpus: 0 1 2 3 4 5 12 13 14 15 16 17
node 0 size: 32756 MB
node 0 free: 19642 MB
node 1 cpus: 6 7 8 9 10 11 18 19 20 21 22 23
node 1 size: 32768 MB
node 1 free: 18652 MB
node distances:
node 0 1
0: 10 21
1: 21 10
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# numa默认的内存分配策略:
1.缺省(default):总是在本地节点分配(分配在当前进程运行的节点上); 2.绑定(bind):强制分配到指定节点上; 3.交叉(interleave):在所有节点或者指定的节点上交织分配; 4.优先(preferred):在指定节点上分配,失败则在其他节点上分配。
$ 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 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95
cpubind: 0 1
nodebind: 0 1
membind: 0 1
2
3
4
5
6
7
# mysql等指定interleave
对于mysql等占用内存比较多的应用,在numa local 内存不足时,上述策略会优先淘汰/Swap本Chip上的内存,使得大量有用内存被换出。当被换出页被访问时就会出现数据库响应时间飙高甚至阻塞。参考https://www.cnblogs.com/cenalulu/p/4358802.html (opens new window)
解决方法,修改为interleave:
# 轮询分配内存
numactl --interleave=all ./program args
2
# 执行程序时指定numa配置:
# 运行 program 程序,参数是 argument,绑定到cpu11, 内存分配时分配node 1 的内存
numactl --physcpubind=11 --membind=1 ./program args
# 优先考虑从 node 1 上分配内存
numactl --preferred=1
2
3
4
5
6
7
8
# 冷函数问题的 membind 和 numa_balancing
不常访问的函数偶尔访问时(几秒一次),可能会出现延迟较高的情况,比如原来是1us,冷的情况下是3us,perf中观察到有较多的minor-fault(page-fault)
使用numactl --membind 将程序的cpu和mem绑定到同一节点上后,会大大减少perf中观察到的minor-fault(page-fault)的次数,同样会在延迟,只比原来的1us增加几百ns
关闭numa_balancing可起到和membind类似的效果,具体情况需实际测试。
# 关闭numa_balancing
echo 0 > /proc/sys/kernel/numa_balancing
# 查看numa_balancing
sysctl -a | grep numa
2
3
4
5