如何用好你的CPU,NUMA小笔记

背景

NUMA 这个词干运维的同学一定不陌生,因为往往会唤起很多惨痛的血泪史,个人认为NUMA作为CPU发展的一个必然趋势,是很值得好好学习(复习)一下的。

CPU 架构的进化

关于什么是NUMA,我们可以拆开我们的笔记本电脑看一下,会发现哪怕有多个CPU的槽位,但依然只有一根线接入到内存条那里,类似下面那个逻辑图:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ex3ObT4u-1603987772920)(DB9E72D35C4A4ABFAAAC503EB1C80984)]

对,这个CPU架构,不是NUMA,这种古老的架构被叫做SMP(Symmetric Multiprocessing),设想一样, 每个CPU必须通过相同的内存总线访问相同的内存资源,而SMP架构下CPU又是被均匀的分配使用的,导致了一旦CPU增加,"车流量"一大,是不是在内存总线上"撞车"的几率就大大增大了,所以SMP的扩容性很差,一般也就一些无需扩容的设备上使用,比如手机,老式的笔记本等等。由于SMP是共享所有内存的,所以这种架构也叫UMA(Uniform Memory Access),顺便一提,如果不想拆笔记本也可以使用下面的命令看下你的CPU架构:

 ls /sys/devices/system/node/# 如果只看到一个node0 那就是smp架构

那NUMA是啥大概也就能猜到了,NUMA(Non-Uniform Memory Access)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7RNxtDN2-1603987772926)(D9E22F9CED1F4E5F81165F08FD46A1E7)]

回想一下UMA的主要问题在于CPU的扩展性,再想一想几年前大家用的CPU是几Core,现在是几Core,就知道在这个各种超频能随便变出几十个core的年代,UMA的确不是很适用了,所以NUMA 也逐渐流行起来。

当然CPU架构肯定不止这2种,比如MPP也是不错,但刀片服务器没怎么玩过,就不再细说了。

Linux 如何使用NUMA?

Linux 对待NUMA的想法就很简单了,既然做你出来是为了防止共享一整块内存导致的"翻车",那我在kernel的内存分配上只要默认遵循以下策略即可:

优先尝试当前请求线程所在的CPU的本地Mem上分配空间, 如果本地内存不足, 如果本地内存不足,则优先干掉本地内存中无用的page

前半句还好,看到后半句是否回忆起之前发生的种种故障了么? “KVM虚拟机所在宿主机明明资源没有满,为啥机器上的redis性能一下子差了呢”,"我的MYSQL怎么用着用着就慢了呢?"诸如此类,大体上就是上面那个策略作梗,不过都说是默认策略,当然可以改:

cat /proc/sys/vm/zone_reclaim_mode = 1 
# 如果为0的话,那么系统会倾向于从其他node分配内存# 如果为1的话,那么系统会倾向于从本地node回收Cache内存cat /proc/sys/vm/overcommit_memory = 0# 0:表示内核将检查是否有足够的可用内存供应用进程使用;如果有足够的可用内存,内存申请允许;否则,内存申请失败,并把错误返回给应用进程。# 1:表示内核允许分配所有的物理内存,而不管当前的内存状态如何。# 2:表示内核允许分配超过所有物理内存和交换空间总和的内存

当然改内核比较是个全局操作,numactl 支持基于应用上直接修改

numactl --interleave=all serverA start #所有node节点进行交织分配的策略

顺便补充下numactl的一些常用参数

--show #整体情况--hardware #查看当前numa的硬件使用情况,比如多少个node之类的--interleave=nodes #all 或者0, 1, 从其他node找内存,all 其实就相当于numa 关闭了--membind=nodes #只从某节点分配内存,当某节点内存不足,则会分配失败,node 是数字,比如0,1--cpunodebind=nodes #进程绑定到某节点上--physcpubind=cpus #把进程绑定到某几个Core上,比如1,3--localalloc #命令永远在当前节点分配内存--preferred=node #如果指定的内存无法分配足够的空间,可以指定去某一个节点的内存分

还有numastat ,可以查看当前numa 各个node的使用情况

numastat
 numa_hit #当前节点本地内存分配总大小
 numa_miss #当前节点访问remote node的内存大小。
 numa_foreign #remote node 访问当前节点的内存大小
 interleave_hit #interleave策略下从当前节点分配的次数
 local_node #当前节点的进程成功在这个节点上分配内存访问的大小
 other_node #当前节点的进在remote node上分配的内存访问大小

开启/关闭NUMA
NUMA 开启/关闭一般3种方式, bios, os, 以及cli。

bios 方法每个服务器都有差异,主要记录一下os和cli

#OS 直接改grub即可/boot/grub/grub.conf
在kernel 那一列的最后直接加 numa=on(off)即可cat /proc/cmdline#cli 启动方式直接在numactl

               

上一篇:x86服务器虚拟化的资源划分和性能优化


下一篇:os方向论文推荐:NrOS: Effective Replication and Sharing in an Operating System