NUMA 感知的实时迁移

https://blueprints.launchpad.net/nova/+spec/numa-aware-live-migration

当具有 NUMA 特性的实例进行实时迁移时,这些特性不会在目标计算主机上重新计算。在 CPU pinning 的情况下,在目标主机上使用源主机的 pin 映射可能导致多个实例被 pinned 到相同的 pCPUs。对于 hugepage 备份的实例,它们是 NUMA 本地化的,实例需要在实时迁移期间在目标计算主机上重新计算其 NUMA 映射。

问题描述

在以下段落中,术语 NUMA 被错误地用来表示 InstanceNUMATopology 对象中表达的任何客户机特性,例如 CPU pinning 和 hugepages。CPU pinning 可以在没有客户机 NUMA topology 的情况下实现,但由于没有比 NUMA 更好的术语,因此将继续使用它。

这个问题可以用三个例子来最好地描述。

第一个例子是带有 CPU pinning 的实时迁移。一个具有 dedicated CPU 策略和 pinned CPUs 的实例被实时迁移。它的 pin 映射被简单地复制到目标主机。这会产生两个问题。首先,它的 pinned pCPUs 在目标主机上没有被正确声明。这意味着,如果第二个具有 pinned CPUs 的实例降落在目标主机上,两个实例的 vCPUs 可能会被 pinned 到相同的 pCPUs。其次,目标主机上现有的 pin 映射被忽略。如果另一个实例已经存在于目标主机上,两个实例的 vCPUs 可能会被 pinned 到相同的 pCPUs。在两种情况下,dedicated CPU 策略被违反,可能导致不可预测的性能下降。

第二个例子是具有 hugepages 的实例。有两个主机,每个主机有两个 NUMA 节点和每个节点 8 个 1GB hugepages。两个相同的实例启动在两个主机上。它们的虚拟 NUMA topology 是一个虚拟 NUMA 节点和 8 个 1GB 内存页。它们降落在各自主机上的 NUMA 节点 0 上,消耗了它的所有 8 个页。一个实例被实时迁移到另一个主机。libvirt 驱动程序强制执行严格的 NUMA 亲和性,并且不会重新生成实例 XML。两个实例最终都位于主机的 NUMA 节点 0 上,并且实时迁移的实例无法运行。

第三个例子是一个具有虚拟 NUMA topology(但没有 hugepages)的实例。如果一个与主机 NUMA 节点 2 关联的实例被实时迁移到一个只有两个 NUMA 节点的主机,因此没有 NUMA 节点 2,它将无法运行。

前两个例子是已知的 bug [1] [2]

用例

作为云管理员,我希望实时迁移具有 CPU pinning 的实例,而无需在目标计算主机上重叠 pin 映射。

作为云管理员,我希望 hugepage 备份的实例的实时迁移能够工作,并且实例能够在目标计算主机上成功运行。

作为云管理员,我希望具有显式 NUMA topology 的实例的实时迁移能够工作,并且实例能够在目标计算主机上成功运行。

提议的变更

目前,调度器不声明任何 NUMA 资源。虽然已经开始将 NUMA topology 作为 placement 中的资源提供者进行建模 [3],但此 spec 故意忽略这项工作,并且不依赖它。相反,将继续使用当前声明 NUMA 资源的方法。具体来说,NUMA 资源将继续由计算主机的资源跟踪器声明。

在 cell conductor(实时迁移不支持跨 cell,因此 superconductor 不涉及)和计算级别,当前实时迁移流程的相关部分可以通过以下简化的伪序列图来概括。

+-----------+                        +---------+                             +-------------+ +---------+
| Conductor |                        | Source  |                             | Destination | | Driver  |
+-----------+                        +---------+                             +-------------+ +---------+
      |                                   |                                         |             |
      | check_can_live_migrate_destination|                                         |             |
      |---------------------------------------------------------------------------->|             |
      |                                   |                                         |             |
      |                                   |           check_can_live_migrate_source |             |
      |                                   |<----------------------------------------|             |
      |                                   |                                         |             |
      |                                   | migrate_data                            |             |
      |                                   |---------------------------------------->|             |
      |                                   |                                         |             |
      |                                   |                            migrate_data |             |
      |<----------------------------------------------------------------------------|             |
      |                                   |                                         |             |
      | live_migration(migrate_data)      |                                         |             |
      |---------------------------------->|                                         |             |
      |                                   |                                         |             |
      |                                   | pre_live_migration(migrate_data)        |             |
      |                                   |---------------------------------------->|             |
      |                                   |                                         |             |
      |                                   |                            migrate_data |             |
      |                                   |<----------------------------------------|             |
      |                                   |                                         |             |
      |                                   | live_migration(migrate_data)            |             |
      |                                   |------------------------------------------------------>|
      |                                   |                                         |             |

migrate_data 是一个 LiveMigrateData 对象。此 spec 建议添加一个包含 InstanceNUMATopology 对象的对象字段。源将把实例的现有 NUMA topology 包含在 migrate_data 中,该 migrate_data 将从其 check_can_live_migrate_source 返回到目标主机。目标的 virt 驱动程序将此 InstanceNUMATopology 拟合到目标的 NUMATopology 并使用资源跟踪器声明资源。然后,它会将更新的 InstanceNUMATopology 作为现有 migrate_data 的一部分发送回 conductor,该 migrate_data 来自 check_can_live_migrate_destination。更新的 InstanceNUMATopology 将继续作为 migrate_data 的一部分传播,最终到达源。源的 libvirt 驱动程序将使用此更新的 InstanceNUMATopology 在生成要发送到目标的实时迁移实例 XML 时。

+-----------+                                                   +---------+                                +-------------+                                      +---------+
| Conductor |                                                   | Source  |                                | Destination |                                      | Driver  |
+-----------+                                                   +---------+                                +-------------+                                      +---------+
      |                                                              |                                            |                                                  |
      | check_can_live_migrate_destination                           |                                            |                                                  |
      |---------------------------------------------------------------------------------------------------------->|                                                  |
      |                                                              |                                            |                                                  |
      |                                                              |              check_can_live_migrate_source |                                                  |
      |                                                              |<-------------------------------------------|                                                  |
      |                                                              |                                            |                                                  |
      |                                                              | migrate_data + InstanceNUMATopology        |                                                  |
      |                                                              |------------------------------------------->|                                                  |
      |                                                              |                                            | --------------------------------------------\    |
      |                                                              |                                            |-| Fit InstanceNUMATopology to NUMATopology, |    |
      |                                                              |                                            | | fail live migration if unable             |    |
      |                                                              |                                            | |-------------------------------------------|    |
      |                                                              |    migrate_data + new InstanceNUMATopology |                                                  |
      |<----------------------------------------------------------------------------------------------------------|                                                  |
      |                                                              |                                            |                                                  |
      | live_migration(migrate_data + new InstanceNUMATopology)      |                                            |                                                  |
      |------------------------------------------------------------->|                                            |                                                  |
      |                                  --------------------------\ |                                            |                                                  |
      |                                  | pre_live_migration call |-|                                            |                                                  |
      |                                  |-------------------------| |                                            |                                                  |
      |                                                              |                                            |                                                  |
      |                                                              | live_migration(migrate_data + new InstanceNUMATopology)                                       |
      |                                                              |---------------------------------------------------------------------------------------------->|
      |                                                              |                                            |            ------------------------------------\ |
      |                                                              |                                            |            | generate NUMA XML for destination |-|
      |                                                              |                                            |            |-----------------------------------| |
      |                                                              |                                            |                                                  |

在早期(在 check_can_live_migrate_source 而不是 pre_live_migration 中)交换实例 NUMA topology 是为了在目标主机无法容纳实例时尽快失败。如果计算主机没有都运行更新的握手代码,会发生什么情况在 ref:upgrade-impact 中讨论。

目前,只有 placement 分配在实时迁移期间更新。建议的资源跟踪器声明机制一旦实现了 NUMA 资源提供者 [3] 就会过时。因此,作为一种临时的错误处理方法,如果目标计算主机上的资源声明失败,则可以使实时迁移失败。一旦 NUMA 由 placement 处理,计算主机将不需要执行任何资源声明。

在目标计算主机有机会声明它们之前,另一个实例可能会从实时迁移的实例那里窃取 NUMA 资源。在实现了 NUMA 资源提供者 [3] 并允许基本上是原子调度+声明操作之前,调度和声明将继续在不同的节点上不同的时间进行。因此,竞争的潜力将继续存在。

备选方案

可以重用从调度器调用 numa_fit_instance_to_host 的结果,在实时迁移到达 conductor 之前。调度器中的 select_destinationsSelection 对象列表返回给 conductor 的实时迁移任务。可以修改 Selection 对象以包含 InstanceNUMATopology。NUMA topology 过滤器可以为每个通过的 host 添加一个 InstanceNUMATopology。该 topology 最终会到达 conductor,然后将其放入 migrate_data 中。目标计算主机然后将按之前描述的方式声明资源。

数据模型影响

InstanceNUMATopology 被添加到 LiveMigrateData

REST API 影响

无。

安全影响

无。

通知影响

无。

其他最终用户影响

无。

性能影响

无。

其他部署者影响

无。

开发人员影响

无。

升级影响

无。

假设,NUMA 感知的实时迁移如何在版本不匹配的计算主机之间支持取决于哪个计算主机较旧。

如果目标主机比源主机旧,则源主机不会在 migrate_data 中获得 InstanceNUMATopology,因此可以选择运行旧式实时迁移。

如果源主机比目标主机旧,则 LiveMigrateData 中的新字段将被忽略,并且源主机的旧实时迁移将不会出现问题。但是,目标主机已经声明了源主机不生成实例 XML 的 NUMA 资源。目标主机可以设想检查源主机的计算服务版本,并在源主机不支持 NUMA 实时迁移时在声明资源之前使迁移失败。

然而,鉴于 NUMA 实时迁移当前中断的状态,一个更简单的解决方案是拒绝执行 NUMA 实时迁移,除非源主机和目标主机都已升级到支持它的版本。为此,conductor 可以检查源主机和目标主机的计算服务版本,如果其中任何一个太旧,则使迁移失败。

实现

负责人

主要负责人

notartom

工作项

  • InstanceNUMATopology 添加到 LiveMigrateData

  • 修改 libvirt 驱动程序以基于从目标主机收到的 migrate_data 中的 InstanceNUMATopolgy 生成实时迁移实例 XML。

依赖项

无。

测试

gate 中使用的 libvirt/qemu 驱动程序当前不支持 NUMA 功能(尽管正在进行工作 [4])。因此,在 upstream gate 中测试 NUMA 感知实时迁移将需要嵌套 virt。此外,NUMA 实时迁移测试的可断言结果(如果它最终成为可能)将是实时迁移成功。检查实例 XML 以断言有关其 NUMA 亲和性或 CPU pin 映射的内容明确超出 tempest 的范围。出于这些原因,最好在第三方 CI [5] 或其他下游测试场景 [6] 中测试 NUMA 感知实时迁移。

文档影响

当前的实时迁移文档没有在任何地方提及 NUMA 限制。因此,解释实时迁移的新 NUMA 功能的 release note 就足够了。

参考资料

历史

修订

发布名称

描述

Rocky

引入