通过ID链接计算对象¶
https://blueprints.launchpad.net/nova/+spec/compute-object-ids
Nova 长期以来依赖于计算节点上不变的主机名。本规范旨在解决此限制,至少从检测意外更改并避免数据库中可能因主机名更改(无论是故意的还是意外的)而导致的灾难的角度来看。
作为增强计算主机名工作的一部分,本规范描述了下一阶段,涉及加强计算节点管理的数据库对象之间的链接。
问题描述¶
ComputeNode、Service 和 Instance 对象构成了我们计算节点的主要数据模型。实例在计算节点上运行,由服务管理。我们依赖这种层次结构来了解实例的位置(物理位置)以及将管理消息发送到哪个 RPC 端点。目前,所有三个对象之间的链接相对松散且基于字符串的关联,使用计算节点的主机名和/或 CONF.host 值。这不仅使实际/有意的重命名变得非常困难,而且还可能因意外重命名而导致关键链接中断。
用例¶
作为一名操作员,我希望意外或瞬态的主机名重命名不会导致 Nova 数据结构的损坏。
作为一名开发人员,我希望数据模型中的主要对象之间有更强的关联,以提高鲁棒性和性能。
提议的变更¶
我们已经在 ComputeNode 对象上有一个 service_id 字段。我们应该在创建新的 ComputeNode 时恢复填充它,并且我们应该在 ComputeManager.init_host() 期间修复现有记录,类似于我们如何在本次努力的早期阶段添加主机名差异检查。
我们需要向 Instance 对象添加一个 compute_id 字段,这将需要架构迁移。该字段需要保持可为空,并且对于调度前的实例以及处于 SHELVED_OFFLOADED 状态的实例,该字段将为 NULL。 可以在我们当前设置 Instance.node 的同时填充 compute_id 字段,并且类似于上面的 ComputeNode 记录,我们可以在 ComputeManager._init_instance() 期间迁移现有记录。为了确保我们保持 node 和 compute_id 字段同步,Instance.create() 和 Instance.update() 方法将执行检查,以确保前者不会在不更改后者的情况下更改。此检查将(由于这两个 @remotable 方法的性质)在 conductor 节点上运行,并且仅当对象的版本足够新时才会强制执行要求。
很多时候我们更新 Instance.node,都是从 Migration 对象进行的,使用 source_node 用于还原的迁移或 dest_node 用于成功的迁移。因此,我们的迁移处理也需要进行一些工作,如下文所述。
重要的是要注意,本规范定义了分两部分进行的工作的一部分。此处描述的设置需要在所有数据迁移完成后,更改我们查找这些对象的方式以使用新的关系,才能进行后续步骤。
迁移处理¶
目前,我们在许多地方从 Migration 对象更新 Instance.node。在这些情况中的大多数情况下,它是在实例将保留的节点上执行的。对于这些情况,我们将从资源跟踪器(仍然通过名称,来自 Migration 对象)获取 ComputeNode 对象,并使用它来设置新的字段。除了每次需要它时节省一次松散耦合的数据库查找之外,这还有助于双重检查 Migration 对象中指定的节点(松散地,通过名称)是当前主机的正确节点(或其中一个节点)。
我们目前从非实例将保留的主机位置更新 Instance.node 的唯一位置是在重调大小的早期部分,其中 _resize_instance() 在发送主机上运行,并由目标主机提供信息。在这种情况下,我们将修改 Migration 对象以包含一个额外的 dest_compute_id 字段,该字段将由目标主机填充其已知正确的value,供发送主机在修改 Instance.node(和 Instance.compute_id)时使用,以成为新主机的value。
升级问题¶
由于 Instance 和 Migration 对象将增长新的字段,旧节点在旧节点和新节点之间迁移时将不会填充这些字段。对于 Instance,compute_id 字段在后续版本中知道它已被填充之前才会被实际使用。如果存在 Migration 中的 dest_compute_id 字段,将使用它,如果不存在,则回退到查找节点的 ID 将依赖于对 ComputeNode.get_by_host_and_nodename() 的调用,这“很容易”,因为 Migration 具有进行此调用的所有字段。
备选方案¶
这不是正确操作所必需的,因此我们可以选择不执行任何操作。
我们也可以选择保留基于字符串的关联,并通过外键关系进行加强。
对于 Migration 的更改,我们也可以使目标计算 ID 成为从目标计算返回到源以避免更改 Migration 对象的新 RPC 参数。但是,这会带来更多的升级问题。
我们也可以在 Migration 对象上使用 ComputeNode.uuid 而不是 ID。没有真正的理由这样做,因为跨单元格迁移已经创建了两个迁移对象,每个单元格一个。它还会表现更差,并且不会是我们需要在实例上设置的字段的 1:1 映射,这意味着还需要进行另一次数据库查找。
数据模型影响¶
所有更改将限制在单元格数据库中
Instance 将增长一个
compute_id字段Migration 将增长一个
dest_compute_id字段需要将一致性检查添加到对象的生命周期操作中。
ComputeNode 现有的
service_id字段将被填充两者将在创建新记录时填充,并在
nova-compute启动时填充现有记录。
REST API 影响¶
无
安全影响¶
无
通知影响¶
无
其他最终用户影响¶
无
性能影响¶
虽然这不是主要意图,但后续工作将能够通过整数 ID 关系而不是通过字符串来查询这些对象,这应该更快,并且对数据库服务器的影响更小。
其他部署者影响¶
除了升级后的下一次启动后的少量在线数据迁移流量外,没有额外的部署器影响,以及在工作完成后提高性能和鲁棒性。
开发人员影响¶
关于对象关系基于 ID 而不是主机名的一些额外的重新学习。
升级影响¶
这里没有实际的升级影响,除了已经预期的影响。将添加一个简单的数据库迁移,无需对排序或同时的代码更改有任何特定要求。计算节点将在升级后首次重新启动期间迁移现有记录。
实现¶
负责人¶
- 主要负责人
danms
工作项¶
在创建时开始填充
ComputeNode.service_id在启动时(
init_host())迁移现有的ComputeNode对象添加一个迁移以添加
Instance.compute_id和Migration.dest_compute_id字段开始为迁移填充
Migration.dest_compute_id在完成调度和迁移后开始填充
Instance.compute_id。在启动时(
_init_instance())迁移现有的Instance对象
依赖项¶
无
测试¶
将添加单元和功能测试,以验证新的和现有的对象是否正确链接和迁移。
文档影响¶
不需要文档更改。
参考资料¶
历史¶
发布名称 |
描述 |
|---|---|
2023.2 Bobcat |
引入 |