NUMA简单介绍
NUMA:(Non Uniform Memory Access)即非一致内存访问架构。
NUMA具有多个节点(Node),每个节点可以拥有多个CPU(每个CPU可以具有多个核或线程),节点内使用共有的内存控制器,因此节点的所有内存对于本节点的所有CPU都是等同的,而对于其它节点中的所有CPU都是不同的。节点可分为本地节点(Local Node)、邻居节点(Neighbour Node)和远端节点(Remote Node)三种类型。
本地节点:对于某个节点中的所有CPU,此节点称为本地节点;
邻居节点:与本地节点相邻的节点称为邻居节点;
远端节点:非本地节点或邻居节点的节点,称为远端节点。
邻居节点和远端节点,称作非本地节点。
CPU访问不同类型节点内存的速度是不相同的:本地节点>邻居节点>远端节点。访问本地节点的速度最快,访问远端节点的速度最慢,即访问速度与节点的距离有关,距离越远访问速度越慢。考虑到上述问题,业务在部署虚拟机时很多情况下要求绑核。
Nova简单介绍
Nova是OpenStack的核心组件,用于管理计算资源,实现对计算资源的分配、调度和销毁等操作。Nova这一组件包含了许多的小组件,其中有API Server (nova-api)、Message Queue (rabbit-mq server)、Compute Workers (nova-compute)、Network Controller (nova-network)、Scheduler (nova-scheduler)和Conductor(nova-conductor)等。具体的组件的作用不在本文介绍范围,后续详细介绍。
Nova中使用NUMA
K版本开始使用numa机制进行,为了便于numa资源的管理以及使用,在nova数据库的comoute_nodes表中使用numa_topology字段来记录,但是numa_topology的支持是有版本要求的:
Libvirt:X86下1.2.7及以上版本,PPC下1.2.19及以上版本;
Qemu:2.1.0版本及以上。
Libvirt以及qemu版本的查看方法:
图1 Libvirt版本查看
支持numa的系统中nova上报的numa cpu信息如下:
"cpuset": [0, 1, 2, 3, 8, 9, 10, 11], "pinned_cpus": [], "id": 0, "siblings": [[3, 11], [0, 8], [1, 9], [2, 10]],"cpuset": [4, 5, 6, 7, 12, 13, 14, 15], "pinned_cpus": [], "id": 1, "siblings": [[7, 15], [4, 12], [5, 13], [6, 14]]
Id: numa node的编号;
Cpuset:该node上的cpu列表;
pinned_cpus:该node上已经被虚拟机绑定的cpu列表;
siblings:该node上核间的亲和关系,成对的表示在同一个物理核上。
Nova中cpu相关设置
部署虚拟机时需要指定虚拟机使用的物理节点的numa相关信息才能保证虚拟机按照自己的要求进行部署,否则系统将不会进行任何的绑定,并且使用的numa节点也不确定。
hw:numa_nodes:虚拟机使用物理机的numa node的数量。一般情况为1或2,设置为1时主要考虑让虚拟机部署于一个numa节点之内时能提高效能,但是很多情况下部署的虚拟机的核数以及内存要求比较大时设置为1就不合适了,需要让虚拟机使用两个node。
hw:numa_cpus.0:该配置项指定物理机某个node上承接的虚拟机cpu的数量。如果此项没有配置,则虚拟机的cpu按照numa_nodes数量和vcpu数量平均分配。即物理机上单个numa节点内承接vcpu/numa_nodes的数量个vcpu。
hw:numa_mem.0:与hw:numa_cpus.0配对使用,用于指明物理机某个numa node上承接的虚拟机的内存数量。
hw:cpu_policy:虚拟机的绑核策略,即虚拟机的vcpu与物理机的pcpu是不是进行绑定。取值为shared或者dedicated,默认是shared。其中shared表示分配到某一个numa节点的多个vcpu会共享该node内的pcpu;dedicated表示精确绑核,即vcpu会精确绑定到某个特定pcpu。
还有一些设置可以决定虚拟机内部CPU的呈现形式:
hw:cpu_sockets - 优选 socket 数量
hw:cpu_cores - 优选 core 数量
hw:cpu_threads - 优选 thread 数量
hw:cpu_maxsockets - 最大socket数
hw:cpu_maxcores - 最大core数量
hw:cpu_maxthreads - 最大 thread 数量
注意
1)hw:numa_mem.0与hw:numa_cpus.0配对使用,即两者必须同时指定,同时,几个node上mem累加后不得超过flavor内存。
2)带编号的几个配置中的编号并不是说0就一定部署在物理机的0号numa节点上,而仅仅用来说明一个逻辑编号。
3)如果配置了hw:numa_nodes数量,则绑核时会根据这个数量把cpu绑核到一个或者多个物理numa节点上。如果绑核策略为share,则如果numa_nodes为1或者没配置,则vcpu会被限定在某个node中的pcpu中漂移;如果numa_nodes配置为2,则vcpu会按照数量在两个node中的pcpu进行漂移。如果绑核策略为dedicated,则绑核时会根据hw:numa_nodes数量把vcpu绑核到不同的物理numa节点上。
4)所有的配置项都支持flavor或者image中配置,只是image中对应的配置为hw_配置项的形式,如果image和flavor中都做了配置,则以image中的配置为准。
设置方法
1)flavor中设置方法
命令:nova flavor-key flavor_id set 配置项=value
2)image中设置方法
命令:glance image-update --property 配置项=value image_id
相关问题 1) 指定为核绑定策略为dedicated时不支持内存以及cpu超分。
2) 设置为dedicated核绑定策略时,如果numa过滤器找不到合适的host,则查看是是否因cpu资源不足失败的方法为:
找到nova数据库中的compute_nodes表的numa_topology列中如下信息:
"cpuset": [0, 1, 2, 3, 8, 9, 10, 11], "pinned_cpus": [], "id": 0, "siblings": [[3, 11], [0, 8], [1, 9], [2, 10]],
"cpuset": [4, 5, 6, 7, 12, 13, 14, 15], "pinned_cpus": [], "id": 1, "siblings": [[7, 15], [4, 12], [5, 13], [6, 14]]
{"cells": [{"cpu_usage": 0, "memory_usage": 0, "cpuset": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41], "memory": 130951, "pinned_cpus": [], "pcpuset": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41], "siblings": [[9, 37], [11, 39], [34, 6], [40, 12], [33, 5], [10, 38], [2, 30], [41, 13], [35, 7], [3, 31], [32, 4], [1, 29], [8, 36], [0, 28]], "id": 0}]}
查看node上cpuset-pinned_cpus后的cpu的数量是否小于虚拟机要求的node节点上cpu的数量。
3) 虚拟机创建后cpu绑核情况的查看方法:
virsh vcpupin 虚拟机uuid/instance name
如下表示虚拟机的vcpu未绑核
sudo virsh vcpupin instance-000008fe
VCPU: CPU Affinity
----------------------------------0: 0-551: 0-55
如下表示虚拟机的vcpu已绑核