CPU topologies

OpenStack 中的 NUMA 拓扑和 CPU pinning 功能提供了对实例在 hypervisor CPU 上运行方式以及实例可用的虚拟 CPU 拓扑的高级控制。这些功能有助于最大限度地减少延迟并最大限度地提高性能。

重要提示

在 Train 之前的部署中,或在正在进行滚动升级的 Stein/Train 混合部署中,除非明确 启用,使用 libvirt 驱动程序时,具有 NUMA 拓扑结构的实例的实时迁移是不可能的。NUMA 拓扑结构可以显式指定,或者由于使用 CPU pinning 或 huge pages 而隐式添加。有关更多信息,请参阅 bug #1289064。从 Train 开始,使用 libvirt 驱动程序时,具有 NUMA 拓扑结构的实例的实时迁移完全受支持。

SMP、NUMA 和 SMT

对称多处理 (SMP)

SMP 是一种在许多现代多核系统中发现的设计。在 SMP 系统中,有两个或多个 CPU,这些 CPU 通过某种互连连接。这使得 CPU 可以平等地访问系统资源,如内存和输入/输出端口。

非统一内存访问 (NUMA)

NUMA 是 SMP 设计的一种衍生品,它在许多多插槽系统中被发现。在 NUMA 系统中,系统内存被划分为与特定 CPU 关联的单元或节点。可以通过互连总线请求其他节点上的内存。但是,通过此共享总线的带宽是有限的。因此,对该资源的竞争可能会导致性能下降。

同步多线程 (SMT)

SMT 是一种与 SMP 互补的设计。虽然 SMP 系统中的 CPU 共享总线和一些内存,但 SMT 系统中的 CPU 共享更多的组件。共享组件的 CPU 被称为线程兄弟。所有 CPU 都显示为系统上可用的 CPU,并且可以并行执行工作负载。但是,与 NUMA 一样,线程也会争夺共享资源。

非统一 I/O 访问 (NUMA I/O)

在 NUMA 系统中,对映射到本地内存区域的设备的 I/O 比对远程设备的 I/O 更有效。连接到与 CPU 和内存提供相同插槽的设备,由于其物理邻近性,可以为 I/O 操作提供更低的延迟。这通常体现在连接到 PCIe 总线的设备中,例如 NIC 或 vGPU,但适用于支持内存映射 I/O 的任何设备。

在 OpenStack 中,SMP CPU 被称为 *核心*,NUMA 单元或节点被称为 *插槽*,SMT CPU 被称为 *线程*。例如,一个具有 Hyper-Threading 的四插槽八核系统将具有四个插槽,每个插槽八个核心,每个核心两个线程,总共 64 个 CPU。

PCPU 和 VCPU

PCPU

表示为单个客户机分配的专用 CPU 数量的资源类。

VCPU

表示单个客户机的 CPU 资源的单位,近似于单个物理处理器的处理能力。

自定义实例 NUMA 放置策略

重要提示

以下描述的功能当前仅受 libvirt/KVM 驱动程序支持。

在 NUMA 主机上运行工作负载时,重要的是执行进程的 vCPU 位于与这些进程使用的内存相同的 NUMA 节点上。这可确保所有内存访问都位于节点本地,从而不会消耗有限的跨节点内存带宽,从而增加内存访问的延迟。同样,大页是从内存分配的,并受益于与使用标准页面分配的内存相同的性能改进。因此,它们也应该是本地的。最后,PCI 设备直接与特定的 NUMA 节点关联,以进行 DMA 目的。使用 PCI 或 SR-IOV 设备的实例应放置在与这些设备关联的 NUMA 节点上。

NUMA 拓扑可以存在于主机的物理硬件和实例的虚拟硬件上。在 OpenStack 中,在启动进程时,hypervisor 驱动程序会查看实例和正在启动的主机的 NUMA 拓扑字段,并使用该信息生成适当的配置。

默认情况下,实例在主机的所有 NUMA 节点上浮动。可以通过使用大页或 pinned CPU 或通过使用 flavor extra specs 或 image metadata 隐式地启用 NUMA 感知。如果实例请求了特定的 NUMA 拓扑,compute 将尝试将实例的不同 NUMA 单元的 vCPU pinned 到主机上相应的 NUMA 单元。它还会将实例的 NUMA 拓扑暴露给客户机操作系统。

在所有使用 NUMA 感知的情况下,必须启用 NUMATopologyFilter 过滤器。有关此过滤器的详细信息,请参阅 计算调度程序

主机 NUMA 节点的使用方式基于某种逻辑并由 nova.conf 中的 packing_host_numa_cells_allocation_strategy 配置变量控制。默认情况下,packing_host_numa_cells_allocation_strategy 变量设置为 True。它会导致首先选择具有较少可用资源的 NUMA 节点(或者说,**更繁忙**的 NUMA 节点)。这是一种“pack”策略 - 我们尝试将尽可能多的负载放置在**更繁忙**的主机 NUMA 节点上,直到它完全耗尽。只有在耗尽后,我们才会从主机上剩余的可用节点中选择**最繁忙**的主机 NUMA 节点。“spread”策略与“pack”策略相反。将首先使用具有**更多可用**资源的 NUMA 节点。因此,“spread”策略将尝试在所有 NUMA 节点之间平衡负载,并尽可能保持所有 NUMA 节点上的可用资源数量相等。

警告

主机 NUMA 节点放置在列表中,并且根据所选策略和每个 NUMA 节点中可用的资源对列表进行排序。排序是按相同列表一个接一个执行的,因此最后实现的排序优先级最高。

python 执行所谓的稳定排序。这意味着对相同列表执行的每个排序只会更改列表项的顺序,如果排序的项属性不同。如果所有列表项中的这些属性都相等,则元素顺序不会更改。

对主机 NUMA 节点列表执行以下顺序的排序

  • 基于节点可用内存的排序(第一优先级排序)

  • 基于 CPU 使用率的排序(如果客户机 VM 拓扑请求共享 CPU)或否则基于空闲 pinned CPU 的排序。

  • 基于节点上空闲 PCI 设备数量的排序(最后优先级排序)

最高排序优先级是附加了 PCI 设备的宿主 NUMA 节点。如果 VM 请求了 PCI 设备,逻辑**始终**将具有更多 PCI 设备的宿主 NUMA 节点放置在宿主 NUMA 节点列表的开头。如果 VM 没有请求 PCI 设备,则具有较少(或没有)可用 PCI 设备的 NUMA 节点将放置在列表的开头。

警告

上述逻辑用于 PCI 设备**同时**用于“pack”和“spread”策略。这是为了保持与先前 nova 版本的向后兼容性。

在“pack”逻辑实现期间,其余两个排序以排序顺序执行,以将具有更多可用资源(CPU 和内存)的 NUMA 节点移动到主机 NUMA 节点列表的末尾。基于内存的排序是首先实现的排序,优先级最低。

在“spread”逻辑实现期间,其余两个排序以排序顺序执行,以将具有更多可用资源(CPU 和内存)的 NUMA 节点移动到主机 NUMA 节点列表的开头。基于内存的排序是首先实现的排序,优先级最低。

最后,将结果列表(在所有排序之后)传递给下一个,并尝试从列表中的第一个主机 NUMA 节点开始将 VM 的 NUMA 节点放置到主机 NUMA 节点。

警告

节点资源不足会导致调度失败。特定于节点的资源不仅包括 CPU 和内存,还包括 PCI 和 SR-IOV 资源。在不请求多节点布局的情况下,无法使用来自不同节点的多个资源。因此,可能需要确保 PCI 或 SR-IOV 资源与相同的 NUMA 节点关联,或强制执行多节点布局。

如果使用 NUMA 感知,则实例的操作系统可以智能地调度其运行的工作负载并最大限度地减少跨节点内存带宽。要配置客户机 NUMA 节点,可以使用 hw:numa_nodes flavor extra spec。例如,要将实例的 vCPU 限制为单个主机 NUMA 节点,请运行

$ openstack flavor set $FLAVOR --property hw:numa_nodes=1

对于具有非常苛刻的内存访问延迟或带宽要求的某些工作负载,超过单个 NUMA 节点可用的内存带宽,将实例扩展到多个主机 NUMA 节点是有益的,即使实例的 RAM/vCPU 在理论上可以适应单个 NUMA 节点。要强制实例的 vCPU 扩展到两个主机 NUMA 节点,请运行

$ openstack flavor set $FLAVOR --property hw:numa_nodes=2

可以配置实例 vCPU 和内存从不同主机 NUMA 节点的分配。这允许不对称分配 vCPU 和内存,这对于某些工作负载非常重要。可以使用 hw:numa_cpus.{num}hw:numa_mem.{num} extra specs 分别配置实例 vCPU 和内存跨每个**客户机**NUMA 节点的分配。例如,要将实例的 6 个 vCPU 和 6 GB 内存扩展到两个 NUMA 节点,并在两个节点之间创建 1:2 的 vCPU 和内存映射,请运行

$ openstack flavor set $FLAVOR --property hw:numa_nodes=2
# configure guest node 0
$ openstack flavor set $FLAVOR \
  --property hw:numa_cpus.0=0,1 \
  --property hw:numa_mem.0=2048
# configure guest node 1
$ openstack flavor set $FLAVOR \
  --property hw:numa_cpus.1=2,3,4,5 \
  --property hw:numa_mem.1=4096

注意

{num} 参数是 *客户机* NUMA 节点的索引,可能不对应于 *主机* NUMA 节点。例如,在具有两个 NUMA 节点的平台上,调度程序可以选择将 hw:numa_mem.0 中引用的客户机 NUMA 节点 0 放置在主机 NUMA 节点 1 上,反之亦然。同样,在 hw:numa_cpus.{num} 的值中指定的 CPU 位掩码引用 *客户机* vCPU,可能不对应于 *主机* CPU。因此,此功能不能用于将实例限制为特定的主机 CPU 或 NUMA 节点。

警告

如果 hw:numa_cpus.{num}hw:numa_mem.{num} 的组合值大于可用 CPU 或内存的数量,将引发异常。

有关 hw:numa_nodeshw:numa_cpus.Nhw:num_mem.N 的语法,请参阅 Extra Specs

自定义实例 CPU pinning 策略

重要提示

以下描述的功能当前仅受 libvirt/KVM 驱动程序支持,并且需要 一些主机配置 才能使其工作。

注意

实例中公开的 NUMA 拓扑与实例实际 pinned 到主机上的方式之间没有关联。这是设计使然。有关更多信息,请参阅此 无效的 bug

默认情况下,实例 vCPU 进程不会分配给任何特定的主机 CPU,而是像任何其他进程一样在主机 CPU 上浮动。这允许 CPU 过度提交等功能。在高度争用的系统中,这以牺牲单个实例的性能和延迟为代价,提供了最佳的系统性能。

某些工作负载需要实时或接近实时行为,这在使用默认 CPU 策略引入的延迟是不可能的。对于此类工作负载,控制哪些主机 CPU 绑定到实例的 vCPU 有益。此过程称为 pinning。具有 pinned CPU 的实例不能使用另一个 pinned 实例的 CPU,从而防止实例之间的资源争用。

CPU pinning 策略可用于确定是否应 pinned 实例。可以使用 hw:cpu_policy extra spec 和等效的 image metadata 属性进行配置。有三种策略:dedicatedmixedshared(默认)。dedicated CPU 策略用于指定实例的所有 CPU 都应使用 pinned CPU。要配置 flavor 以使用 dedicated CPU 策略,请运行

$ openstack flavor set $FLAVOR --property hw:cpu_policy=dedicated

这通过确保使用 PCPU 分配而不是 VCPU 分配来实现。因此,也可以显式请求此资源类型。要配置此项,请运行

$ openstack flavor set $FLAVOR --property resources:PCPU=N

(其中 N 是 flavor 中定义的 vCPU 数量)。

注意

目前无法在同一实例中请求 PCPUVCPU 资源。

shared CPU 策略用于指定实例**不应**使用 pinned CPU。要配置 flavor 以使用 shared CPU 策略,请运行

$ openstack flavor set $FLAVOR --property hw:cpu_policy=shared

mixed CPU 策略用于指定实例使用 pinned CPU 以及未 pinned CPU。实例 pinned CPU 可以在 hw:cpu_dedicated_mask 中指定,或者,如果启用了 实时,则在 hw:cpu_realtime_mask extra spec 中指定。例如,要配置 flavor 以使用 mixed CPU 策略,总共 4 个 vCPU,并且前 2 个 vCPU 作为 pinned CPU,请运行

$ openstack flavor set $FLAVOR \
  --vcpus=4 \
  --property hw:cpu_policy=mixed \
  --property hw:cpu_dedicated_mask=0-1

要配置 flavor 以使用 mixed CPU 策略,总共 4 个 vCPU,并且前 2 个 vCPU 作为 pinned **实时** CPU,请运行

$ openstack flavor set $FLAVOR \
  --vcpus=4 \
  --property hw:cpu_policy=mixed \
  --property hw:cpu_realtime=yes \
  --property hw:cpu_realtime_mask=0-1

注意

有关 hw:cpu_policyhw:cpu_dedicated_maskhw:realtime_cpuhw:cpu_realtime_mask 的语法,请参阅 Extra Specs

注意

有关实时功能的更多信息,请参阅 文档

也可以通过 image metadata 配置 CPU 策略。这在打包需要实时或接近实时行为的应用程序时很有用,因为它可确保使用给定 image 创建的实例始终 pinned,而与 flavor 无关。要配置 image 以使用 dedicated CPU 策略,请运行

$ openstack image set $IMAGE --property hw_cpu_policy=dedicated

同样,要配置 image 以使用 shared CPU 策略,请运行

$ openstack image set $IMAGE --property hw_cpu_policy=shared

注意

有关 image metadata 的更多信息,请参阅 Image metadata 指南。

重要提示

基于风味的策略优先于基于镜像的策略。例如,如果某个风味指定了 CPU 策略为 dedicated(专用),那么该策略将被使用。如果风味指定 CPU 策略为 shared(共享),并且镜像没有指定策略或指定策略为 shared,那么 shared 策略将被使用。但是,如果风味指定 CPU 策略为 shared,而镜像指定策略为 dedicated,反之亦然,将会引发异常。这是设计使然。镜像元数据通常可以由非管理员用户配置,而风味只能由管理员配置。通过在风味扩展规格中设置 shared 策略,管理员可以防止用户在镜像中配置 CPU 策略,从而影响资源利用率。

自定义实例 CPU 线程绑定策略

重要提示

以下描述的功能需要使用绑定的实例,因此目前仅受 libvirt/KVM 驱动程序支持,并且需要 一些主机配置 才能使其工作。

在 SMT 主机上运行绑定实例时,还需要考虑线程兄弟对实例工作负载的影响。像 Intel Hyper-Threading 这样的 SMT 实现可以为某些工作负载提高 高达 30% 的性能。但是,线程兄弟共享许多组件,这些组件上的争用会降低其他工作负载的性能。因此,也可以显式请求带有或不带有 SMT 的主机。

要配置实例是否应该放置在带有 SMT 的主机上,可以指定 CPU 线程策略。对于共享能提高性能的工作负载,您可以请求带有 SMT 的主机。要配置此项,请运行

$ openstack flavor set $FLAVOR \
  --property hw:cpu_policy=dedicated \
  --property hw:cpu_thread_policy=require

这将通过请求报告 HW_CPU_HYPERTHREADING 特性的主机,来确保实例被调度到带有 SMT 的主机上。也可以显式请求此特性。要配置此项,请运行

$ openstack flavor set $FLAVOR \
  --property resources:PCPU=N \
  --property trait:HW_CPU_HYPERTHREADING=required

对于性能受资源争用影响的其他工作负载,您可以请求不带有 SMT 的主机。要配置此项,请运行

$ openstack flavor set $FLAVOR \
  --property hw:cpu_policy=dedicated \
  --property hw:cpu_thread_policy=isolate

这将通过请求不报告 HW_CPU_HYPERTHREADING 特性的主机,来确保实例被调度到不带有 SMT 的主机上。也可以显式请求此特性。要配置此项,请运行

$ openstack flavor set $FLAVOR \
  --property resources:PCPU=N \
  --property trait:HW_CPU_HYPERTHREADING=forbidden

最后,对于性能影响最小的工作负载,如果可用可以使用线程兄弟,否则可以不使用它们。这是默认设置,但可以显式设置

$ openstack flavor set $FLAVOR \
  --property hw:cpu_policy=dedicated \
  --property hw:cpu_thread_policy=prefer

这不使用特性,因此没有基于特性的等效项。

注意

有关 hw:cpu_thread_policy 语法的更多信息,请参阅 扩展规格

与 CPU 策略一样,也可以通过镜像元数据配置 CPU 线程策略。这在打包需要实时或近实时行为的应用程序时很有用,通过确保使用给定镜像创建的实例始终被绑定,而不管风味如何。要配置镜像以使用 require CPU 策略,请运行

$ openstack image set $IMAGE \
  --property hw_cpu_policy=dedicated \
  --property hw_cpu_thread_policy=require

同样,要配置镜像以使用 isolate CPU 线程策略,请运行

$ openstack image set $IMAGE \
  --property hw_cpu_policy=dedicated \
  --property hw_cpu_thread_policy=isolate

最后,要配置镜像以使用 prefer CPU 线程策略,请运行

$ openstack image set $IMAGE \
  --property hw_cpu_policy=dedicated \
  --property hw_cpu_thread_policy=prefer

如果风味没有指定 CPU 线程策略,则镜像指定的 CPU 线程策略(如果有)将被使用。如果风味和镜像都指定了 CPU 线程策略,则它们必须指定相同的策略,否则将引发异常。

注意

有关 image metadata 的更多信息,请参阅 Image metadata 指南。

自定义实例模拟器线程绑定策略

重要提示

以下描述的功能需要使用绑定的实例,因此目前仅受 libvirt/KVM 驱动程序支持,并且需要 一些主机配置 才能使其工作。

除了在实例中运行的客户操作系统和应用程序的工作之外,底层虚拟机监控程序还存在少量开销。默认情况下,这些开销任务(统称为模拟器线程)在与实例相同的宿主 CPU 上运行,这将导致实例的性能略有下降。通常这不是问题,但是对于实时实例而言,模拟器线程窃取实例 CPU 时间可能不可接受。

可以使用模拟器线程策略来确保模拟器线程在与实例使用的核心不同的核心上运行。有两种策略:isolate(隔离)和 share(共享)。默认情况下,模拟器线程在同一核心上运行。isolate 模拟器线程策略用于指定给定实例的模拟器线程应在其自己的唯一核心上运行,该核心从列在 compute.cpu_dedicated_set 中的一个或多个宿主核心中选择。要配置风味以使用 isolate 模拟器线程策略,请运行

$ openstack flavor set $FLAVOR \
  --property hw:cpu_policy=dedicated \
  --property hw:emulator_threads_policy=isolate

share 策略用于指定给定实例的模拟器线程应在列在 compute.cpu_shared_set 中的宿主核心池上运行(如果已配置),否则在实例的所有 pCPU 上运行。要配置风味以使用 share 模拟器线程策略,请运行

$ openstack flavor set $FLAVOR \
  --property hw:cpu_policy=dedicated \
  --property hw:emulator_threads_policy=share

上述行为可以用下表总结

compute.cpu_shared_set 已设置

compute.cpu_shared_set 未设置

hw:emulator_treads_policy 未设置(默认)

绑定到实例的所有 pCPU

绑定到实例的所有 pCPU

hw:emulator_threads_policy = share

绑定到 compute.cpu_shared_set

绑定到实例的所有 pCPU

hw:emulator_threads_policy = isolate

绑定到与实例的 pCPU 不同的单个 pCPU

绑定到与实例的 pCPU 不同的单个 pCPU

注意

有关 hw:emulator_threads_policy 语法的更多信息,请参阅 hw:emulator_threads_policy

自定义实例 CPU 拓扑

重要提示

以下描述的功能当前仅受 libvirt/KVM 驱动程序支持。

注意

目前它也适用于 libvirt/QEMU 驱动程序,但我们不建议在生产用例中使用它。这是因为 vCPU 实际上在 qemu TCG(Tiny Code Generator)中运行在一个线程上,TCG 是 libvirt/QEMU 驱动程序的后端。QEMU 社区正在进行一项工作,以启用 TCG 的完全多线程支持(也称为 MTTCG)。请参阅此 MTTCG 项目 页面以获取详细信息。

除了配置实例如何在宿主 CPU 上调度之外,还可以配置实例本身如何表示 CPU。默认情况下,如果未指定实例 NUMA 放置,则实例使用 N 个插槽的拓扑,每个插槽有一个核心和一个线程,其中 N 对应于请求的实例 vCPU 数。如果指定了实例 NUMA 放置,则插槽数固定为要使用的宿主 NUMA 节点数,并且实例 CPU 总数在这些插槽上拆分。

某些工作负载受益于自定义拓扑。例如,在某些操作系统中,根据 CPU 插槽的数量可能需要不同的许可证。要配置风味以使用两个插槽,请运行

$ openstack flavor set $FLAVOR --property hw:cpu_sockets=2

类似地,要配置风味以使用一个核心和一个线程,请运行

$ openstack flavor set $FLAVOR \
  --property hw:cpu_cores=1 \
  --property hw:cpu_threads=1

警告

如果指定所有值,则插槽数乘以核心数乘以线程数的乘积必须等于实例 vCPU 数。如果指定其中任何一个值或两个值的倍数,则这些值必须是实例 vCPU 数的因子,以防止出现异常。例如,在具有奇数个核心的宿主机上指定 hw:cpu_sockets=2 失败。同样,在具有十个核心的宿主机上指定 hw:cpu_cores=2hw:cpu_threads=4 失败。

有关 hw:cpu_socketshw:cpu_coreshw:cpu_threads 语法的更多信息,请参阅 扩展规格

也可以设置插槽、核心和线程数量的上限。与上述硬值不同,不需要使用确切的数字,因为它仅提供限制。这可以在调度中提供一些灵活性,同时确保不超过某些限制。例如,要确保不超过两个插槽、八个核心和一个线程在实例拓扑中定义,请运行

$ openstack flavor set $FLAVOR \
  --property hw:cpu_max_sockets=2 \
  --property hw:cpu_max_cores=8 \
  --property hw:cpu_max_threads=1

有关 hw:cpu_max_socketshw:cpu_max_coreshw:cpu_max_threads 语法的更多信息,请参阅 扩展规格

应用程序通常打包为镜像。对于喜欢特定 CPU 拓扑的应用程序,请配置镜像元数据以提示创建的实例应具有给定的拓扑,而不管风味如何。要配置镜像以请求具有两个插槽、每个插槽四个核心的拓扑,请运行

$ openstack image set $IMAGE \
  --property hw_cpu_sockets=2 \
  --property hw_cpu_cores=4

要限制实例的插槽、核心或线程数量,请使用 max_ 变体。要配置镜像以具有最多两个插槽和最多一个线程,请运行

$ openstack image set $IMAGE \
  --property hw_cpu_max_sockets=2 \
  --property hw_cpu_max_threads=1

风味中指定的值被视为绝对限制。镜像限制不得超过风味限制,只能等于或低于风味定义的限制。通过为插槽、核心或线程设置 max 值,管理员可以防止用户配置可能产生额外许可费用的拓扑。

有关 image metadata 的更多信息,请参阅 Image metadata 指南。

配置 libvirt 计算节点以进行 CPU 绑定

版本 20.0.0 中已更改: 在 20.0.0(Train)之前,无需显式配置主机以进行绑定的实例。但是,无法将绑定的实例放置在与未绑定的 CPU 相同的宿主机上,这通常意味着必须将宿主机分组到宿主机聚合中。如果未这样做,未绑定的实例将继续在所有启用的宿主 CPU 上浮动,即使某些实例 CPU 已绑定也是如此。从 20.0.0 开始,必须显式标识应用于绑定实例的宿主核心。

Nova 处理用于未绑定实例的宿主 CPU 的方式与用于绑定实例的宿主 CPU 的方式不同。前者在放置中使用 VCPU 资源类型进行跟踪,可以超额分配,而后者使用 PCPU 资源类型进行跟踪。默认情况下,nova 会报告所有宿主 CPU 作为 VCPU 库存,但是可以使用 compute.cpu_shared_set 配置选项来配置,以指定应将哪些宿主 CPU 用于 VCPU 库存,以及 compute.cpu_dedicated_set 配置选项,以指定应将哪些宿主 CPU 用于 PCPU 库存。

考虑一个具有 24 个宿主物理 CPU 核心且已启用超线程的计算节点。操作员希望为宿主处理(不用于客户实例)保留 1 个物理 CPU 核心及其线程兄弟。此外,操作员希望使用 8 个宿主物理 CPU 核心及其线程兄弟作为专用的客户 CPU 资源。剩余的 15 个宿主物理 CPU 核心及其线程兄弟将用于共享的客户 vCPU 使用,这些物理处理器用于共享客户 CPU 资源的分配比例为 8:1。

操作员可以像这样配置 nova.conf

[DEFAULT]
cpu_allocation_ratio=8.0

[compute]
cpu_dedicated_set=2-17
cpu_shared_set=18-47

virt 驱动程序将构建一个包含单个资源提供程序表示计算节点和相应报告 PCPUVCPU 库存的提供程序树。

COMPUTE NODE provider
    PCPU:
        total: 16
        reserved: 0
        min_unit: 1
        max_unit: 16
        step_size: 1
        allocation_ratio: 1.0
    VCPU:
        total: 30
        reserved: 0
        min_unit: 1
        max_unit: 30
        step_size: 1
        allocation_ratio: 8.0

使用 dedicated CPU 策略或显式 PCPU 资源请求的实例将消耗 PCPU 库存。同时,使用 shared CPU 策略的实例将消耗 VCPU 库存。

注意

PCPUVCPU 分配目前结合起来计算 cores 配额类别的数值。

配置专用核心的 CPU 功耗管理

版本 27.0.0 中更改:此功能仅由 2023.1 Antelope 版本引入

重要提示

以下描述的功能当前仅受 libvirt/KVM 驱动程序支持。

出于节能原因,操作员可以决定关闭 CPU 核心的功耗,无论它们是否正在使用。出于显而易见的原因,Nova 仅允许更改专用 CPU 核心的功耗,而不允许更改共享 CPU 核心的功耗。因此,使用此功能依赖于读取 compute.cpu_dedicated_set 配置选项,以了解要处理哪些 CPU 核心。启用专用核心的功耗管理的主要操作是将 libvirt.cpu_power_management 配置选项设置为 True

默认情况下,如果启用此选项,Nova 将在计算服务启动时查找专用核心并关闭它们。然后,一旦实例通过附加到专用核心而启动,该核心将在 libvirt 客户机启动之前被打开。另一方面,一旦实例停止、迁移或删除,相应的专用核心将被关闭。

有两种不同的电源开启或关闭策略

  • 默认情况下是使 CPU 核心离线并在需要时将其置于在线状态。

  • 另一种策略是为上电状态和断电状态使用两个不同的 CPU 调速器。

可以使用 libvirt.cpu_power_management_strategy 配置选项选择策略。 cpu_state 支持第一种在线/离线策略,而 governor 设置另一种策略。我们默认关闭核心,因为它提供了最佳的节能效果,而其他工具(例如 tuned)可以管理调速器。也就是说,我们还提供了一种动态更改调速器的方法,如下所述。

重要提示

某些操作系统平台不支持 sysfs 中的 cpufreq 资源,因此 governor 策略可能不可用。请在修改配置选项之前,验证您的操作系统是否支持缩放调速器。

如果策略设置为 governor,则提供了一对配置选项来定义用于上电状态和断电状态的精确 CPU 调速器

重要提示

操作员的责任是确保配置选项定义的调速器当前受运行计算服务的操作系统内核支持。

作为补充说明,我们建议将 schedutil 调速器作为高功耗状态的替代方案(如果内核支持它),因为 CPU 频率是根据 CPU 任务状态动态设置的。其他调速器也值得测试,包括 conservativeondemand,它们比 schedutil 功耗更高,但比 performance 更有效。有关更多说明,请参阅 Linux 内核文档

例如,nova.conf 的一部分配置如下所示

[compute]
cpu_dedicated_set=2-17

[libvirt]
cpu_power_management=True
cpu_power_management_strategy=cpu_state

警告

在大多数最新的 Linux 内核中,CPU 核心 #0 具有特殊含义。强烈建议不要将其用于 CPU 固定,但请避免对其进行功耗管理,否则 Nova 关闭它时可能会出现意外情况!

最后一条重要说明:您可以决定在计算生命周期期间更改 CPU 管理策略,或者您可以当前已经管理 CPU 状态。为了确保 Nova 可以正确管理 CPU 性能,我们在启动时添加了一些检查,如果未强制执行这些任意规则,则拒绝启动 nova-compute 服务

  • 如果操作员选择 cpu_state 策略,则所有专用 CPU 调速器必须相同。

  • 如果他们决定使用 governor,则所有专用 CPU 核心必须处于在线状态。