OpenStack NUMA 配置

NUMA 体系架构

  • SMP 体系架构
  • NUMA 体系架构
  • NUMA 结构基本概念
  • Openstack flavor NUMA 策略
  • Nova 实现 NUMA 流程

 1. SMP 体系架构

CPU 计算平台体系架构分为 SMP 体系架构和 NUMA 体系架构等,下图为 SMP 体系架构:node

SMP(Sysmmetric Multi-Processor System,对称多处理器系统),它由多个具备对称关系的处理器组成。所谓对称,即处理器之间是水平的镜像关系,没有主从之分。SMP 架构使得一台计算机再也不由单个 CPU 组成。数据库

SMP 的结构特征是多处理器共享一个集中式存储器,每一个处理器访问存储器的时间片一致,使工做负载可以均匀的分配到全部可用处理器上,极大地提升了整个系统的数据处理能力。可是,若是多个处理器同时请求访问共享资源时,就会引起资源竞争,须要软硬件实现加锁机制来解决这个问题。因此,SMP 又称为 UMA(Uniform Memory Access,一致性存储器访问),其中,一致性指的是在任意时刻,多个处理器只能为内存的每一个数据保存或共享一个惟一的数值。api

所以,这样的架构设计没法拥有良好的处理器数量扩展性,由于共享内存的资源竞态老是存在的,处理器利用率最好的状况只能停留在 2 到 4 颗。缓存

 

2. NUMA 体系架构

计算机系统中,处理器的处理速度要远快于内存的读写速度,因此限制计算机计算性能的瓶颈在存储器带宽上。SMP 架构由于限制了处理器访问存储器的频次,因此处理器可能会时刻对数据访问感到饥饿。架构

NUMA(Non-Uniform Memory Access,非一致性存储器访问)架构优化了 SMP 架构扩展性差以及存储器带宽窄的问题。socket

从上图能够看出,NUMA 和 SMP 架构是相似的,一样只会保存一份操做系统和数据库的副本,表示 NUMA 架构中的处理器依旧可以访问到整个存储器。两种主要的区别在于 NUMA 架构采用了分布式存储器,将处理器和存储器划分为不一样的节点(NUMA Node),每一个节点都包含了若干的处理器与内存资源。多节点的设计有效提升了存储器的带宽和处理器的扩展性。假设系统含有 4 个 NUMA 节点,那么在理想状况下系统的存储器带宽将会是 SMP 架构的 4 倍。分布式

另外一方面,NUMA 节点的处理器能够访问到总体存储器。按照节点内外,内存被分为节点内部的本地内存以及节点外部的远程内存。当处理器访问本地内存时,走的是内部总线,当处理器访问远程内存时,走的是主板上的 QPI 互联模块。访问前者的速度要远快于后者,NUMA(非一致性存储器访问)所以而得名。

性能

3. NUMA 结构基本概念

  • Socket:表示一颗物理 CPU 的封装(物理 CPU 插槽),简称插槽。为了不将逻辑处理器和物理处理器混淆,Intel 将物理处理器称为插槽。
  • Core: 物理 CPU 封装内的独立的一组程序执行的硬件单元,好比寄存器,计算单元等。
  • Thread: 使用超线程技术虚拟出来的逻辑 Core,须要 CPU 支持。为了便于区分,逻辑 Core 通常被写做 Processor。在具备 Intel 超线程技术的处理器上,每一个内核能够具备两个逻辑处理器,这两个逻辑处理器共享大多数内核资源(如内存缓存和功能单元)。此类逻辑处理器一般称为 Thread 。优化

  • Node: 包含有若干个物理 CPU 的组。

上图的  NUMA Topology 有 2 个 NUMA node,每一个 node 有 1 个 socket,即 pCPU, 每一个 pCPU 有 6 个 core,1 个 core 有 2 个 Processor,则共有逻辑 cpu processor 24 个。ui

在 LIUNX 命令行中执行 lscpu 便可看到机器的 NUMA 拓扑结构:

如上图所示,机器有 2 个 node 分配到 2 个 socket 上,每一个 socket 有 14 个 core,每一个 core 有 2 个 processor, 则共有 56 个 cpu processor。同时,从上图也可看出 NUMA node 0 上的 cpu 分布为 0-13,28-41,而 node 1 上的分布为 14-27, 42-55。

由上节分析知,NUMA node 处理器访问本地内存的速度要快于访问远端内存的速度。访问速度与 node 的距离有关系,node 间的距离称为 node distance,使用  numactl --hardware  能够 show 出该距离:

node0 的本地内存大小为 32209MB,Node1 的本地内存大小为 32316MB。Node0 到本地内存的 distance 为 10,到 node1 的内存 distance 距离为 20。node1 到本地内存的 distance 为10,到 node0 的内存distance距离为20。

进一步对上面的 NUMA Topology 图进行介绍。

Liunx 上使用 cat /proc/cpuinfo 命令 show 出 cpu 信息:

其中 physical  id 表示 socket 号。当前的 cpu core 是第 14 个 ,siblings 为 28 表示此 cpu14 在 core14 里面的兄弟逻辑 cpu 为 cpu28。CPU 14 和 CPU 28 共享 L1 Data cache、L1 instruction 和 L2 Cache 。

[***@controller-0 ~]$ cat /sys/devices/system/cpu/cpu14/cache/index0/type
Data
[***@controller-0 ~]$ cat /sys/devices/system/cpu/cpu14/cache/index1/type
Instruction
[***@controller-0 ~]$ cat /sys/devices/system/cpu/cpu14/cache/index2/type
Unified
[***@controller-0 ~]$ cat /sys/devices/system/cpu/cpu14/cache/index0/size
32K
[***@controller-0 ~]$ cat /sys/devices/system/cpu/cpu14/cache/index1/size
32K
[***@controller-0 ~]$ cat /sys/devices/system/cpu/cpu14/cache/index2/size
256K

 

4. Openstack flavor NUMA 策略

cpu 绑核策略

 对 Libvirt 驱动而言,虚拟机的 vCPU 能够绑定到主机的物理 CPU 上(pCPU)。这些配置能够改善虚拟机实例的精确度与性能。

 openstack flavor set FLAVOR-NAME \
    --property hw:cpu_policy=CPU-POLICY \
    --property hw:cpu_thread_policy=CPU-THREAD-POLICY

有效的CPU-POLICY值为:

  • shared (默认值) : 虚拟机的 vCPU 容许在主机 pCPU 上自由浮动,尽管可能受到 NUMA 策略的限制。
  • dedicated: 虚拟机 vCPU 被严格绑定到一组主机 pCPU 上。

有效的 CPU-THREAD-POLICY 值为:

  • prefer (默认值) : 主机多是也可能不是 SMT 架构,若是应用 SMT 架构时,优选兄弟线程。
  • isolate: 应用在主机可能不是 SMT 架构,或者必须模拟非 SMT 架构。当主机不是 SMT 架构时,每一个 vCPU 至关于一个核。若是主机应用 SMT 架构,也就是说一个物理核有多个兄弟线程,每一个 vCPU 也至关于一个物理核。其余虚拟机的 vCPU 不会放在同一个核上。选中的核上只有一个兄弟线程可用。
  • require: 主机必要使用 SMT 架构。每一个 vCPU 被分配在兄弟线程上。若是主机没有 SMT 架构,那就不使用此主机。若是主机使用 SMT 架构,却没有足够空闲线程的核,那么 nova 调度失败。
有一点要注意的是 cpu_thread_policy 只在 hw:cpu_policy 设置为 dedicated 时才有效。

NUMA拓扑

Libvirt 驱动程序能够为虚拟机 vCPU 定义放置的 NUMA 节点,或者定义虚拟机从哪一个 NUMA 节点分配 vCPU 与内存。

$ openstack flavor set FLAVOR-NAME \
    --property hw:numa_nodes=FLAVOR-NODES \
    --property hw:numa_cpus.N=FLAVOR-CORES \
    --property hw:numa_mem.N=FLAVOR-MEMORY
  • FLAVOR-NODES: 限制虚拟机 vCPU 线程运行的可选 NUMA 节点数量。若是不指定,则 vCPU 线程能够运行在任意可用的 NUMA 节点上。
  • N:  应用 CPU 或内存配置的虚拟机 NUMA 节点,值的范围从 0 到 FLAVOR-NODES - 1。好比为 0,则运行在NUMA节点 0,为 1,则运行在 NUMA 节点1。
  • FLAVOR-CORES: 映射到虚拟机NUMA节点N上的虚拟机vCPU列表。若是不指定,vCPU 在可用的 NUMA 节点之间平均分配。
  • FLAVOR-MEMORY: 映射到虚拟机 NUMA 节点 N 上的虚拟机内存大小。若是不指定,则内存平均分配到可用 NUMA 节点。

举例以下:

$ openstack flavor set aze-FLAVOR \
    --property hw:numa_nodes=2 \
    --property hw:numa_cpus.0=0,1 \ 
    --property hw:numa_cpus.1=2,3 \
    --property hw:numa_mem.0=2048 \
    --property hw:numa_mem.1=2048 \
Flavor 定义虚拟机有 4 个 vCPU,4096MB 内存,它们分布在 2 个 NUMA 节点上。虚拟机的 0 号与 1 号 vCPU 在 NUMA 0 上,2 号与 3 号 vCPU 在 NUMA 1 上。虚拟机的 2048MB 内存在 NUMA 0 上,另外的 2048MB 内存分配到在 NUMA 1上。
注意:hw:numa_cpus.N 与 hw:numa_mem.N 只在设置 hw:numa_nodes 时有效。N 是虚拟机 NUMA 节点的索引,并不必定对应主机 NUMA 节点。例如,在两个 NUMA 节点的平台,根据 hw:numa_mem.0,调度会选择虚拟机 NUMA 节点 0,可是倒是在主机 NUMA 节点 1 上,反之亦然。相似的,FLAVOR-CORES 也是虚拟机 vCPU 的编号,并不对应与主机 CPU。所以,这个特性不能用来约束虚拟机所处的主机 CPU 与 NUMA 节点。

大页内存分配

$ openstack flavor set FLAVOR-NAME \
    --property hw:mem_page_size=PAGE_SIZE

有效的 PAGE_SIZE 值为:

  • small (默认值): 使用最小的内存页面,例如 x86 平台的 4KB。
  • large: 虚拟机 RAM 使用大页内存。例如 x86 平台的 2MB 或 1G。
  • any: 取决于计算驱动程序。此状况下,Libvirt 驱动可能会尝试寻找内存大页,但最终回落到小页。其余的驱动则可能选择可用策略。

注意:大页内存能够分配给虚拟机内存,而不考虑 Guest OS 是否使用。若是 Guest OS 不使用大页内存,则它值会识别小页。反过来,若是 Guest OS 计划使用大页内存,则必定要给虚拟机分配大页内存。不然虚拟机的性能将不及预期。 

 

5. Nova 实现 NUMA 流程

Nova 实现 NUMA 流程以下所示:

1. nova-api 对 flavor metadata 或 image property 中的 NUMA 配置信息进行解析,生成 Guest NUMA topology,保存为 instance[‘numa_topology’]。

2. nova-scheduler 经过 NUMATopologyFilter 判断 Host NUMA topology 是否可以知足 Guest NUMA topology,进行 ComputeNode 调度。

3. nova-compute 再次经过 instance_claim 检查 Host NUMA 资源是否知足创建 Guest NUMA。

4. nova-compute 创建 Guest NUMA node 和 Host NUMA node 的映射关系,并根据映射关系调用 libvirt driver 生成 XML 文件。

5.  Resource Tracker 会刷新 Host NUMA 资源的使用状况。

相关文章
相关标签/搜索