从 placement 计算配额使用情况¶
https://blueprints.launchpad.net/nova/+spec/count-quota-usage-from-placement
在 Pike 版本中,我们重新设计了配额系统,以计算实际资源使用情况,而不是使用预留并跟踪配额使用情况的单独数据库表。我们通过查询每个 cell 数据库并按项目和用户汇总结果来计算实例、CPU 和 RAM 等资源。这种方法在“处理 cell 宕机”的背景下存在问题。如果某个 cell 变得不可用,其数据库中的资源将无法被计算,并且在 cell 恢复之前不会包含在资源使用情况中。如果操作员正在对 cell 进行维护,或者 cell 数据库遇到问题并且我们无法连接到它,cell 可能会变得不可用。
我们可以通过查询 placement 和 API 数据库来获取资源使用情况,而不是读取单独的 cell 数据库,从而使配额的资源使用情况计数对临时的 cell 宕机具有弹性。
问题描述¶
当我们计算 CPU 和 RAM 的配额资源使用情况时,我们通过读取单独的 cell 数据库并汇总结果来执行此操作。每个实例的 CPU 和 RAM 量都来自 flavor,并存储在数据库中作为 instances 表中的列。因此,每次我们检查配额使用情况是否超过限制时,我们都会查询每个 cell 数据库中的实例 ID 计数以及每个 cell 的 CPU 和 RAM 总和,并将它们汇总以计算资源使用情况。
这种方法对临时的 cell 宕机很敏感,这些宕机可能发生在操作员维护期间,或者如果 cell 数据库遇到问题并且我们无法连接到它。当 cell 不可用时,我们无法计算驻留在该 cell 数据库中的资源使用情况,并且行为就像有比应该更多的配额可用一样。也就是说,如果有人用完了他们的配额,并且其中的一部分在 cell A 中,而 cell A 暂时离线,那么那个人突然能够分配比其限制更多的资源(假设 cell A 返回,那个人将分配比其允许的配额更多的资源)。
我们可以采取不同的方法,通过查询 placement API 和 API 数据库来获取资源使用情况计数。由于 placement 正在管理资源分配,因此它拥有我们需要计算 CPU 和 RAM 配额的资源使用情况的信息。通过查询 placement 和 API 数据库,我们可以避免读取单独的 cell 数据库以获取资源使用情况。
用例¶
从 placement 计算配额资源使用情况将使配额行为在临时的 cell 数据库中断的情况下保持一致。如果需要进行维护,操作员可以更轻松地使 cell 离线,而不必担心可能超过配额限制。它可以省去操作员修复维护期间或无法建立 cell 数据库连接时配额被超过的情况的麻烦。
提议的变更¶
我们将添加一种新的方法来计算实例,该方法查询 API 数据库中的 instance_mappings 表,并为实例数量进行单独的限制检查。
新方法将包含
一个查询 API 数据库以获取实例资源使用情况。如果我们在
nova_api.instance_mappings表中添加一个新列user_id,我们可以获取项目和用户的实例数量。该表已经有一个project_id列。这将允许我们计算项目和用户的实例映射,以表示实例计数。
我们将把 _instances_cores_ram_count 方法重命名为 _cores_ram_count,该方法计算来自 cell 数据库的核心和 RAM,并且仅在 [workarounds]disable_quota_usage_from_placement 为 True 时使用。
由于 placement 尚未提供分配分区功能(或者,资源提供者可以从中派生分区的资源),为了支持多个 Nova 部署共享同一 placement 服务的部署,例如在 Edge 场景中,我们可以添加一个 [workarounds]disable_quota_usage_from_placement,默认值为 False。如果为 True,我们将使用实例、核心和 RAM 的传统配额计数方法。如果为 False,我们将使用调用 placement 的配额计数方法。这是保持“传统”配额计数可用的多个 Nova 部署共享一个 placement 服务的最小方法。配置选项将简单地控制可插拔配额系统调用哪种计数方法。例如(伪代码)
if CONF.workarounds.disable_quota_usage_from_placement:
CountableResource('cores', _cores_ram_count, 'cores')
CountableResource('ram', _cores_ram_count, 'ram')
else:
CountableResource('cores', _cores_ram_count_placement, 'cores')
CountableResource('ram', _cores_ram_count_placement, 'ram')
我们将添加一种新的方法来计算来自 placement 的核心和 RAM,该方法在 [workarounds]disable_quota_usage_from_placement 为 False 时使用。该方法可以命名为 _cores_ram_count_placement。
新方法将包含
一个调用 placement 以获取 CPU 和 RAM 资源使用情况。我们可以通过查询
/usages资源来获取项目和用户的 CPU 和 RAM 使用情况GET /usages?project_id=<project id>&user_id=<user id>
备选方案¶
另一种选择是等到 placement 具有分配分区支持后再开始计算来自 placement 的任何配额使用情况。问题是与此同时,我们处理 cell 宕机的唯一解决方案是实现 基于策略的行为,其中操作员必须在项目在宕机的 cell 中具有实例的情况下选择失败服务器创建请求,或者允许服务器创建请求可能超过配额限制。
另一种讨论过的选择是使用 placement 聚合来包围整个 Nova 部署,并将其用作分割 placement 使用情况的一种方式。在这种情况下,我们需要向 placement /usages API 添加一个 aggregate= 查询参数。这种方法还需要 Nova 或操作员的一些工作来保持 placement 聚合的更新。
数据模型影响¶
需要对 nova_api 数据库模式进行更改,以便将类型为 String 的 user_id 列添加到 nova_api.instance_mappings 表中。
REST API 影响¶
无。
安全影响¶
无。
通知影响¶
无。
其他最终用户影响¶
最终用户即使在 cell 数据库不可用时也能看到一致的配额行为。
性能影响¶
在配额检查时检查是否需要迁移数据会产生性能影响。可以通过缓存指示数据迁移已完成的项目的结果来减少影响,并避免对已迁移的项目进行不必要的检查。
该更改涉及向 placement 发出外部 REST API 调用,而不是并行地将请求分散到所有 cell。如果所有 cell 响应迅速,则发出外部 REST API 调用可能会更慢。如果任何 cell 响应缓慢,则发出外部 REST API 调用可能会更快。
其他部署者影响¶
无。
开发人员影响¶
无。
升级影响¶
将 user_id 列添加到 nova_api.instance_mappings 表中需要迁移所有现有的实例映射以填充 user_id 字段。迁移例程将查找 user_id 为 None 的映射,并按映射中的相应 project_id 查询 cell。查询可以按实例 UUID 过滤,找到要填充到映射中的 user_id 值。这将实现使用 nova-manage db online_data_migrations 进行批量迁移的方式。
我们将会在访问服务器 GET 请求时动态地修复/填充实例映射。这将提供一种数据迁移,以防尚未运行 nova-manage db online_data_migrations 的情况。
为了处理正在进行的升级,我们需要能够在 nova_api.instance_mappings 尚未填充 user_id(如果操作员尚未运行数据迁移)的情况下回退到实例、核心和 RAM 的传统计数方法。我们需要一种方法来检测尚未运行迁移,以便回退到传统计数方法。我们可以进行如下检查:if count(InstanceMapping.id) where project_id=<project id> and user_id=None > 0,然后回退到传统计数方法来查询 cell 数据库。我们应该缓存每个 project_id 的迁移完成情况检查的结果,以便避免对已经迁移的 project_id 进行不必要的检查。
即使对于 queued_for_delete=True 的实例映射,我们也会填充 user_id 字段,因为我们将根据实例映射过滤 queued_for_delete=False 进行基于实例映射的实例计数。
数据迁移和回退到传统计数方法对于 Stein 来说是临时的,将在 T 中通过一个阻塞迁移来删除。也就是说,如果 nova_api.instance_mappings 中有任何 user_id=None,则无法通过 nova-manage api_db sync,以强制使用 nova-manage 进行批量迁移。
实现¶
负责人¶
- 主要负责人
melwitt
- 其他贡献者
无
工作项¶
将
user_id列添加到nova_api.instance_mappings表中。实施在线数据迁移以填充
user_id字段。更新
_server_group_count_members_by_user配额计数方法,以仅使用nova_api.instance_mappings表,而不是查询 cell 数据库。添加配置选项
[workarounds]disable_quota_usage_from_placement,默认值为 False。当 placement 中提供资源提供者或分配的分区时,可以弃用此选项。添加一种新的方法来计算实例,该方法通过过滤
project_id=<project_id>和user_id=<user_id>和queued_for_delete=False来计算nova_api.instance_mappings的计数。添加一种新的计数方法,该方法查询 placement API 以获取 CPU 和 RAM 使用情况。在新计数方法中,添加一个检查,以查看是否已运行在线数据迁移,如果未运行,则回退到传统计数方法。
将
_instances_cores_ram_count方法重命名为_cores_ram_count,并让它仅以传统方式计算核心和 RAM,用于在将[workarounds]disable_quota_usage_from_placement设置为 True 时使用。调整 nova-next 或 nova-live-migration CI 作业,使其使用
[workarounds]disable_quota_usage_from_placement=True运行。
依赖项¶
无。
测试¶
将包含单元测试和功能测试以测试新功能。我们还将调整一个 CI 作业(nova-next 或 nova-live-migration)以使用 [workarounds]disable_quota_usage_from_placement=True 运行,以确保我们拥有该路径的集成测试覆盖范围。
文档影响¶
将更新 Cells v2 警告的文档,以更新有关在一个或多个 cell 不可访问时无法正确计算配额使用情况的段落。我们将记录从 Stein 开始,有新的部署选项。
参考资料¶
这建立在 Pike 中重新设计配额以计算资源所做的工作之上。
这可能还会无意中修复我们遇到的一个错误,即如果“重新检查”配额检查在 conductor 检查期间失败,并且请求是多创建,那么所有服务器都将进入 ERROR 状态,等待用户清理。由于此更改将计算实例映射的实例计数,而实例映射的生命周期几乎与构建请求相同[*],因此如果它们在 conductor 中失败“重新检查”配额,我们不应该看到多创建服务器进入 ERROR 状态的行为。
历史¶
发布名称 |
描述 |
|---|---|
Stein |
引入 |