当前位置: 首页 > 科技观察

让我们一起了解Linux上的Numa架构

时间:2023-03-21 14:06:48 科技观察

本文转载自微信公众号《运维开发故事》,作者无文案夏先生。转载本文请联系运维开发故事公众号。准备环境以下案例基于Ubuntu16.04,同样适用于其他Linux系统。我使用的案例环境如下:机器配置:32个CPU,64GB内存NUMA中存储层次的概念:1)处理器层:单个物理核心,称为处理器层。2)本地节点层:对于某个节点中的所有处理器,该节点称为本地节点。3)归属节点层:与本地节点相邻的节点称为归属节点。4)远程节点层:不是本地节点或邻居节点的节点称为远程节点。不同类型节点的CPU访问内存的速度是不一样的。访问本地节点的速度最快,访问远程节点的速度最慢。也就是说,访问速度与节点的距离有关。距离越远,访问速度越慢。该距离称为生成节点距离。应用程序应尽量减少不同CPU模块之间的交互。如果应用程序可以固定在一个CPU模块中,应用程序的性能将得到很大的提高。再说说搭载鲲鹏920处理器的CPU芯片组成:鲲鹏920处理器SoC的每个超级核心集群包括6个核心集群、2个I/O集群和4个DDR控制器。每个超级核心集群都封装在一个CPU芯片中。每颗芯片集成4条72位(64位数据加8位ECC)高速DDR4通道,数据传输速率高达3200MT/s,单芯片最高可支持512GB×4DDR存储空间。L3Cache在物理上分为两部分:L3CacheTAG和L3CacheDATA。L3缓存TAG集成在每个核心集群中,以减少侦听延迟。L3CacheDATA直接连接到片上总线。HydraHomeAgent(HHA)是一个处理多芯片系统缓存一致性协议的模块。POE_ICL是系统配置的硬件加速器,一般可以作为报文定序器、消息队列、消息分发器,或者实现某个处理器内核的特定任务。此外,每个超级核心集群还物理配置了通用中断控制器分发器(GICD)模块,兼容ARM的GICv4规范。当单芯片或多芯片系统中存在多个超核集群时,系统软件只能看到一个GICD。numactl的使用Linux提供了一个手动调优命令numactl(默认没有安装)。Ubuntu上的安装命令如下:sudoaptinstallnumactl-y首先可以使用mannumactl或者numactl--h来了解参数的作用和输出的内容。查看系统的numa状态:numactl--hardware运行得到如下的结果:available:4nodes(0-3)node0cpus:01234567node0size:16047MBnode0free:3937MBnode1cpus:89101112131415node1size:16126MBnode1free:4554MBnode2cpus:1617181920212223node2size:16126MBnode2free:8403MBnode3cpus:2425262728293031node3size:16126MBnode3free:7774MBnodedistances:node01230:102020201:201020202:202010203:20202010Accordingtothe从这个图和命令得到的结果,可以看出这个系统有4个节点,每个节点接收8个CPU和16G内存。这里还需要注意的是,CPU共享的L3缓存也会自己得到相应的空间。numa状态可以通过numastat命令查看,返回值内容:numa_hit:是内存在本节点分配的次数,最后从本节点开始分配;numa_miss:是计划在本节点分配内存时,从其他节点分配内存的次数;numa_foreign:是内存在其他节点上分配的次数,但最终是从本节点分配的;interleave_hit:interleave策略最终从本节点分配的次数local_node:本节点上的进程在本节点上分配的次数other_node:是其他节点进程在本节点上分配的次数注意:如果发现numa_miss的值比较高,说明需要调整分配策略。比如将指定的进程关联绑定到指定的CPU上,从而提高内存命中率。root@ubuntu:~#numastatnode0node1node2node3numa_hit19480355292111647527601240131190012980472384numa_miss5122680122652623884499517058numa_foreign1226526438844993570555122679interleave_hit12619139421401013924local_node19480308881111647212961240126408912980411641other_node51690911226840878849776267801NUMA的内存分配策略--localalloc或者-l:规定进程从本地节点上请求分配内存。--membind=nodesor-mnodes:Specifiesthattheprocesscanonlyrequestmemoryallocationfromthespecified节点。--preferred=node:指定一个推荐的节点获取内存,如果获取失败,再尝试另一个节点。--interleave=nodesor-inodes:指定进程从指定节点请求与循环算法交错的内存分配。numactl--interleave=allmongod-f/etc/mongod.conf因为NUMA默认的内存分配策略是先在进程所在CPU的本地内存中分配,所以会导致CPU节点间内存分配不均衡。启用swap后,某个CPU节点的内存不足时,会产生swap,而不是从远程节点分配内存。这就是所谓的swapinsanity现象。或导致性能急剧下降。因此,在运维层面,我们还需要关注NUMA架构下的内存使用情况(多个内存节点的使用可能不均衡),合理配置系统参数(内存回收策略/Swap使用倾向),并尽量避免使用Swap。Node->Socket->Core->Processor随着多核技术的发展,多个CPU封装在一起。这个包叫做socket套接字;Core是socket上一个独立的硬件单元;通过intel的超线程HT技术进一步提高CPU的处理能力,以及OS看到的逻辑核心处理器的数量。Socket=NodeSocket是一个物理概念,指的是主板上的CPU插槽;Node是一个逻辑概念,对应于Socket。Core=物理CPUCore是一个物理概念,一个独立的硬件执行单元,对应一个物理CPU;Thread=logicalCPU=ProcessorThread为逻辑CPU,即Processolscpu的用法显示格式:Architecture:架构CPU(s):逻辑cpus的数量Thread(s)percore:每个核心线程,即超线程Core(s)persocket:numberofcorespercpusocket/numberofcoresperphysicalcpuCPUsocket(s):numberofcpusocketsL1dcache:Levelcache(google一下,具体是指cpu的L1数据缓存)L1icache:一级缓存(具体为L1指令缓存)L2cache:二级缓存L3cache:三级缓??存NUMAnode0CPU(s):CPU上的逻辑核心,即超线程执行lscpu,结果如下如下:root@ubuntu:~#lscpuArchitecture:x86_64CPU(s):32Thread(s)percore:1Core(s)persocket:8Socket(s):4L1dcache:32KL1icache:32KL2cache:256KL3cache:20480KNUMAnode0CPU(s):0-7NUMAnode1CPU(s)):8-15NUMAnode2CPU(s):16-23NUMAnode3CPU(s):24-31