Libvirt驱动程序模拟器线程放置策略

https://blueprints.launchpad.net/nova/+spec/libvirt-emulator-threads-policy

Nova调度器根据风味中vCPU的数量确定CPU资源利用率和实例CPU放置。许多hypervisor都在宿主机操作系统中代表客户机实例执行操作。这些操作应该被记录和调度,并且应该应用它们自己的放置策略控制。

问题描述

Nova调度器通过计算为每个客户机分配的vCPU数量来确定CPU资源利用率。在进行超卖时,与专用资源相反,此vCPU数量乘以超卖比例。然后,此利用率用于确定跨计算节点或在NUMA节点内的最佳客户机放置。

然而,许多hypervisor代表客户机实例在与虚拟实例vCPU无关的执行上下文中执行工作。使用KVM / QEMU,有一个或多个线程与QEMU进程相关联,用于QEMU主事件循环、异步I/O操作完成、迁移数据传输、SPICE显示I/O等。使用Xen,如果使用stub-domain功能,则使用整个域来为主域提供I/O后端。

Nova目前没有机制来跟踪这些额外的客户机实例计算需求以衡量利用率,也没有对其执行策略进行任何控制。

libvirt驱动程序已经为KVM实现了一个通用的放置策略,允许QEMU模拟器线程在与实例vCPU运行的相同pCPU上浮动。换句话说,模拟器线程将在它们有工作要做时从vCPU窃取一些时间。在CPU超卖的情况下,这大致可以接受。但是,当客户机想要专用vCPU分配时,希望能够表达其他放置策略,例如,将一个或多个pCPU分配给客户机的模拟器线程专用。随着Nova继续实现对实时工作负载的支持,这将变得至关重要,因为不允许模拟器线程从实时vCPU窃取时间将是不可接受的。

即使libvirt驱动程序可以添加不同的放置策略,除非以某种方式将模拟器线程的概念暴露给调度器,否则无法以令人满意的方式表达CPU使用情况。因此,需要一种方法来向调度器描述可能与客户机关联的其他CPU使用情况,并在放置期间考虑该情况。

用例

使用当前的libvirt实时支持,需要为运行非实时工作负载保留一个vCPU。QEMU模拟器线程被固定在与此vCPU相同的宿主机pCPU上运行。虽然此要求对于Linux客户机来说大致可以接受,但它阻止了Nova运行其他需要对所有vCPU进行实时响应的实时操作系统。为了扩展实时支持,有必要将模拟器线程与vCPU分开固定,这需要调度器能够考虑每个客户机的额外pCPU使用量。

项目优先级

提议的变更

在风味上启用模拟器线程放置策略功能的先决条件是,它还必须将‘hw:cpu_policy’设置为‘dedicated’。

每个hypervisor都有不同的架构,例如QEMU具有模拟器线程,而Xen具有stub-domain。为了避免偏袒任何特定实现,想法是扩展estimate_instance_overhead以返回1个额外的宿主机CPU,以便在声明期间考虑。希望隔离模拟器线程的用户必须使用配置为接受该规范的风味,如下所示:

  • hw:cpu_emulator_threads=isolate

这将表示该实例应被视为消耗1个额外的宿主机CPU。用于运行模拟器线程的pCPU将始终配置在相关的客户机NUMA节点ID 0上,以便用户可以预测它。目前,没有希望自定义运行模拟器线程的宿主机CPU数量,因为在几乎所有使用情况下,只有一个就足够了。如果将来希望隔离多个宿主机CPU来运行模拟器线程,我们将实现I/O线程以增加对在宿主机CPU上运行客户机专用资源的粒度。

正如我们所说,将消耗额外的pCPU,但此首次实现将不会更新用户配额,这是出于简单性的考虑,因为配额已经在不同的场景中泄漏了。

备选方案

我们可以使用主机级别的可调参数来仅为运行模拟器线程全局保留一组主机pCPU,而不是尝试按实例进行计算。这在简单的情况下有效,但当使用NUMA时,拥有更细粒度的配置来控制模拟器线程放置是高度可取的。当使用实时或专用CPU时,将不同KVM实例的模拟器线程分开将至关重要。

另一个选项是硬编码假设风味中设置的vCPU数量隐式包含1个用于模拟器的vCPU。例如,vCPU值为5意味着4个实际vCPU和1个系统伪vCPU。这可能会让租户用户和开发人员感到非常困惑。

什么都不做始终是一个选项。如果我们什么都不做,那么它将限制可以在Nova上运行的工作负载类型。这将对使用专用vCPU功能的用户的产生负面影响,因为将无法保证他们的vCPU不会被模拟器线程抢占。可以通过设置固定策略来在一定程度上通过实时方式解决这个问题,即模拟器线程仅在具有非实时策略的vCPU上运行。这要求所有使用实时操作系统的客户机都是SMP,但有些客户机操作系统想要实时,但仅是UP。

数据模型影响

InstanceNUMATopology对象将被扩展,以包含一个新字段,用于存储请求的策略

  • emulator_threads_policy=CPUEmulatorThreadsPolicy()

此字段将实现为具有两个选项的枚举

  • share - 模拟器线程在与客户机关联的pCPU上浮动。

  • isolate - 模拟器线程隔离在一个pCPU上。

默认情况下将使用‘shared’。重要的是要注意:由于[1]在内核中,使用‘isolcpus=’从命令行隔离CPU上的负载平衡已被删除。这意味着模拟器线程将不会浮动在专用于客户机的pCPU的联合体上,而是被限制在运行vCPU 0的pCPU上。

InstanceNUMACell对象将被扩展,以包含一个新字段,其中将存储物理CPU ID,并由驱动程序层用于固定模拟器线程

  • cpuset_reserved=SetOfIntegersField(nullable=True)

[1] https://kernel.googlesource.com/pub/scm/linux/kernel/git/stable/linux-stable/+/47b8ea7186aae7f474ec4c98f43eaa8da719cd83%5E%21/#F0

REST API 影响

安全影响

通知影响

其他最终用户影响

对于最终用户,使用‘cpu_emulator_threads’选项将消耗与客户机分配的vCPU相关的资源配额中的额外宿主机CPU。

性能影响

NUMA和计算调度器过滤器将进行一些更改,但预计它们不会变得更具计算成本到任何可测量的程度。

其他部署者影响

希望使用该新功能的部署者必须配置其风味以使用专用cpu策略(hw:cpu_policy=dedicated),同时将‘hw:cpu_emulator_threads’设置为‘isolate’。

开发人员影响

  • 其他虚拟化驱动程序的开发人员可能希望使用新的风味额外规范属性和调度器会计。如果使用stub domain功能,这将对Xen hypervisor特别感兴趣。

  • 指标或GUI系统的开发人员必须考虑到将由具有cpu_emulator_threads设置为isolate的实例消耗的宿主机CPU开销。

实现

负责人

主要负责人

sahid-ferdjaoui

其他贡献者

berrange

工作项

  • 增强风味额外规范以考虑hw:cpu_emulator_threads

  • 增强InstanceNUMATopology以考虑cpu_emulator_threads

  • 使资源跟踪器处理带有vcpus的‘estimate_instance_overhead’

  • 扩展libvirt的estimate_instance_overhead

  • 如果请求,使libvirt正确固定模拟器线程。

依赖项

实时规范不是先决条件,但与这项工作互补

测试

可以在任何能够测试当前NUMA和专用CPU策略的CI系统中进行测试。即,它需要能够使用KVM而不仅仅是QEMU。将添加调度和驱动程序位(libvirt)的功能测试。

文档影响

描述NUMA和专用CPU策略使用情况的文档需要扩展到也描述这项工作引入的新选项。

参考资料

历史

修订版

发布名称

描述

Mitaka

提议

Ocata

重新提出

Pike

重新提出