按需生成 PCI 设备池

https://blueprints.launchpad.net/nova/+spec/pci-stats-generate

本提案旨在动态生成 PCI 设备池信息,而不是将汇总池信息存储在数据库中。

问题描述

compute_nodes 表当前在 pci_stats 字段中存储 PCI 设备“池”的 JSON 格式表示。此信息由 nova-compute 资源跟踪器通过 nova.pci.stats.PciDevStats 类更新,并在 Nova 调度器在每次 select_destinations() 调用中,使用 nova.objects.ComputeNodeList.get_all() 方法拉取系统中所有计算节点的信息时读取。调度器拉取此汇总信息的原因是为了避免通过网络发送包含数千条 PCI 设备记录的消息。

将此汇总信息存储在 compute_nodes 表中存在两个问题

1) 汇总信息可能与存储在 pci_devices 表中的非汇总信息不同步,并且

2) 它干扰了我们以一致和通用的方式表示系统中所有资源的工作(资源对象蓝图工作)。

用例

作为 Nova 的开发者,我希望能够以一致和通用的方式表示系统中的所有定量资源。作为操作员,我不想让数据库中的汇总和详细信息不同步。

提议的变更

我们建议对 Nova 代码库进行以下更改

1) 将 nova.pci.stats.PciDevStats.supports_request() 方法的逻辑临时复制到 nova.objects.PciDevicePoolList 对象中。

2) 将确定计算节点是否可以为实例提供请求的 PCI 设备的逻辑从 nova.pci.stats.PciDevStats.consume_requests() 方法移动到 nova.pci.manager.PciDevTracker._claim_for_instance() 方法。

3) 修改 nova.objects.ComputeNode 对象,通过子查询按需加载 pci_device_pools 字段,而不是从数据库中的 compute_nodes.pci_stats 字段中拉取。可以使用对 pci_devices 表的单个 SQL 查询生成 PciDevicePoolList 对象,如下所示

SELECT product_id, vendor_id, numa_node, COUNT(*) as count
FROM pci_devices
WHERE compute_node_id = ?
GROUP BY product_id, vendor_id, numa_node;

这仅用于依赖于 nova.objects.ComputeNode.pci_device_pools 字段属性的旧版计算节点。

4) 更改调度器的主机管理器,使用新的 nova.objects.PciDevicePoolList.get_all 方法加载 PCI 设备池信息,该方法返回所有计算节点的所有 PCI 设备池信息,但仅在启用 PciPassthroughFilter 时才加载。这将与调度器加载主机聚合信息并将其整理到 HostState 对象的方式相匹配。

获取计算节点 PCI 设备池信息的 SQL 语句如下所示

SELECT compute_node_id, product_id, vendor_id, numa_node, COUNT(*) as count
FROM pci_devices
GROUP BY compute_node_id, product_id, vendor_id, numa_node;

5) 更改 nova.scheduler.pci_passthrough_filter.host_passes 方法,使用 nova.objects.PciDevicePoolList.supports_requests() 方法,而不是 nova.pci.stats.PciDevStats.support_requests() 方法。

  1. 完全删除 nova.pci.stats 模块。

7) 在数据库中将 compute_node.pci_stats 字段标记为已弃用,并在 N 版本中标记为删除。

备选方案

无。

数据模型影响

无,这只会更改现有模型定义的实现。

REST API 影响

无。

安全影响

无。

通知影响

无。

其他最终用户影响

无。

性能影响

无。通过网络传输的信息将保持不变。生成汇总 PCI 设备信息的数据库查询应该非常快。

其他部署者影响

无。

开发人员影响

这将允许资源对象蓝图继续进行,因为 PCI 设备资源将能够以与 NUMA 或其他定量资源相同的方式处理。

实现

负责人

主要负责人

dstepanenko

其他贡献者

jaypipes

工作项

1) 将 supports_request() 方法复制到 nova.objects.PciDevicePoolList 对象中。

2) 将 nova.pci.stats.PciDevStats.consume_requests() 移动到 nova.pci.manager.PciDevTracker._claim_for_instance() 方法。

3) 修改 nova.objects.ComputeNode 对象,按需加载 pci_device_pools 字段

4) 更改调度器主机管理器,以与加载主机聚合信息的方式相同加载 PciDevicePoolList 对象,并且仅在启用 PciPassthroughFilter 时才加载。

5) 更改 nova.scheduler.pci_passthrough_filter.host_passes 方法,使用 nova.objects.PciDevicePoolList.supports_requests() 方法

  1. 完全删除 nova.pci.stats 模块。

7) 将数据库中的 nova.db.sqlalchemy.models.ComputeNode.pci_stats 字段标记为已弃用。

依赖项

无。

测试

由于将完全删除递减 PCI 设备池计数的逻辑,因此单元测试的净减少。

文档影响

无。没有面向用户的更改。

参考资料

无。

历史

无。