为数据库添加服务版本号

https://blueprints.launchpad.net/nova/+spec/service-version-number

我们之前已经确定在线数据迁移对于支持实时升级至关重要。在控制服务一起升级(conductor、api 等)的情况下,我们目前在这方面表现良好。为了进一步扩展这一点,我们需要一种方法来确定某些控制服务已经升级,但并非全部。这些信息将允许我们避免在所有服务都升级到可以处理新模式的程度之前进行在线数据升级。

问题描述

部分升级控制服务将导致较新的 conductor 开始将数据转换为扩展到新模式,而较旧的 conductor 和其他控制服务尚未准备好。如果您一起升级所有控制服务,这会很好,但如果您没有这样做(这更现实),您可能会破坏一些较旧的控制服务。

例如,在 Kilo 中,我们可以在开始升级任何代码之前应用数据库模式。但是,一旦我们升级了任何直接与数据库交互的组件,在线迁移就会开始发生,并且任何直接从数据库读取的节点都会感到困惑,因为事情开始发生变化。由于 nova-api、nova-scheduler、nova-conductor 等服务都直接与数据库交互,我们目前无法独立升级这些服务。如果我们有这个服务版本号可用,我们就可以避免在所有受影响的服务都升级到足够新的版本之前进行任何在线迁移。

用例

作为部署者,我希望能够分阶段升级我的控制服务,而无需关闭所有的 conductor、api、scheduler 等节点并一起重启它们,从而跨越实时数据迁移。

项目优先级

这是一个升级增强功能。

提议的变更

提议的更改是在 services 表中添加一个版本号列。每个服务将在更新其服务记录时报告其版本号。我们将能够通过检查表中是否存在多个版本(可选地按服务分组)来确定所有服务是否处于同一代码级别。我们可以使用此信息有条件地启用在线数据迁移。例如,我们可以通过如下方式检查所有 conductor 是否已升级到同一级别

SELECT DISTINCT version FROM services WHERE binary=’conductor’;

如果在 conductor 启动时执行此操作,我们可以设置一个标志,以禁止启用需要 conductor 服务版本高于特定版本的迁移。我们也可以像当前重新加载配置一样在收到 SIGHUP 信号时刷新此信息。

最初,该列将以 NULL 作为默认值创建,并且 Service 对象将 NULL 视为“版本 1”。后续更改会将版本设置为 2。 每次我们执行在线数据迁移时,都需要增加服务版本号。

从长远来看,我们可以尝试将 RPC 版本与此信息关联起来,以方便固定版本。由于这可能对回溯端口(偶尔需要修改 RPC 接口)产生难以量化的影响,我建议我们现在将此排除在本次工作范围之外。即便如此,将 RPC 版本与此服务版本关联起来也是下一轮工作的重点,一旦此功能到位,我们可以依赖它。

另一件事是,这使得服务能够在启动时知道它已经严重过时。 假设我们可以让一个 conductor 启动并说“哇,我比其他 conductor 慢得多,我应该记录一个错误并退出。” 确定最低版本以及应该是什么版本,我们需要在 M 中完成,以便我们可以在 N 和 N-1 版本中使用它,以便我们可以依赖它。

我们需要在 L 中完成此操作,以便我们可以在 M 中利用它。 如果我们将其延迟到 M,我们将无法在 N 中依赖它。

为什么不使用语义化版本控制?

在我们的 RPC API 版本等内容中,我们使用类似于语义化版本控制的版本号。 这使我们能够决定传入的调用以及它们是否与较新的节点兼容,并通常定义什么是破坏性(即主版本号增加)更改。

这个服务版本号本身并不意味着任何语义,而只是提供了一个向量,我们可以利用它来确定时间,从而做出其他决策。 如本文档的其他地方所述,这可能意味着我们可以决定使用哪个 RPC 版本,或者是否可以安全地开始进行在线数据迁移。这些决策从服务版本向量中提取语义含义,并且它们可能具有显著不同的规则(就像上述 RPC 和 DB 决策一样)。

备选方案

我们可以继续像今天一样做,即在推出新代码时立即开始将数据从一个模式转换为另一个模式。 我们仍然保留所有控制服务必须一起更新的限制。

我们也可以将其以某种方式编入配置中,但这需要更多的操作员干预,并增加了出错的可能性。

数据模型影响

将编写一个模式迁移来向表中添加一个版本列。 版本将是一个整数,允许为空,默认值为 NULL。

Service 对象将被扩展以支持此版本,并将 NULL 版本视为版本“1”,这将避免我们对现有的服务记录进行任何数据迁移。 新的保存操作最初将为所有服务写入版本“2”。

REST API 影响

无。

安全影响

无。

通知影响

无。

其他最终用户影响

无。

性能影响

无。

其他部署者影响

这将使升级 nova 服务更容易、更灵活/更宽容,方便部署者。

开发人员影响

开发人员(和审查者)需要确保在任何在线数据迁移中增加服务版本号(例如最近的 flavor 重构)。

实现

负责人

主要负责人

danms

其他贡献者

alaski

工作项

  • 编写模式迁移

  • 更新 sqlalchemy 模型和 service 对象

  • 编写一些对象方法,以帮助以对确定升级可行性友好的方式查询服务版本号。

  • 扩展服务启动代码,以检查版本分布并持久化,以便我们可以将其用作启用迁移的静态标志。

依赖项

无。 这主要是为能够在 M 中进行更有趣的升级进行前期准备。

测试

这应该可以通过单元测试完全测试。

文档影响

理想情况下,这应该使升级所需的文档更少。

参考资料