返回选择对象

https://blueprints.launchpad.net/nova/+spec/return-selection-objects

在 Queens 版本中,我们将改变从 select_destinations() 返回的内容,以便为每个请求的实例提供额外的“备选”主机,以及在每个主机上构建的 allocation_request。 以非结构化数据块返回这些信息会很脆弱且可能令人困惑。 创建一个对象来保存这些数据,并以更简单和文档化的方式使其可访问,会更好得多。

问题描述

在 Queens 版本之前,调度器的 select_destinations() 方法返回一个列表,其中包含一个字典,该字典代表为每个请求的实例选择的主机。 在 Queens 版本中,我们需要向 select_destinations() 的调用者返回更多信息。 我们可以尝试返回 HostDicts 的列表,这代表过去选择的主机,以及位于同一 cell 并且也满足请求资源的零个或多个“备选”主机。 此外,这些主机中的每一个都将伴随着一个字典,用于声明该主机的 allocation_request。 最终结果将是一个列表,每个请求的实例有一个条目。 该列表中的每个条目将是 (HostState, allocation_request) 的 2 元组列表。 HostState 是一个简单的字典,但 allocation_request 本身是一个复杂的嵌套字典。

这些更改的结果意味着返回的数据将是字典、列表和元组的复杂嵌套组合。 这种数据结构既难以理解如何正确使用,又让初次查看代码(甚至离开一段时间后)的开发人员感到困惑。 它也没有版本控制,这意味着无法可靠地跟踪和响应未来的更改。

用例

作为一名经验丰富的 Nova 开发人员,我希望能够编写使用从 select_destinations() 返回的信息的代码,而无需解码复杂的数据结构。

作为 Nova 代码库的新手,我希望能够阅读清晰的代码,以便更快地使用它,并更有信心我的更改不会破坏任何东西。

提议的变更

我们建议创建一个新的 Selection 对象,该对象包含代表单个目标的数据:主机信息以及声明所需的相关 allocation_request。 目前包含 hostname、nodename 和 limits 键的字典中的主机信息,现在将作为简单的对象字段存储,以及 allocation_request。 此外,还将添加 compute_node_uuid 字段,因为在我们的分配清理任务中,拥有此字段会很有用。

不需要相应的 SelectionList 对象,因为不需要数据库创建或检索。 select_destinations() 方法将返回简单的 Python Selection 对象列表。 调度器将为每个请求的实例返回一个 Selection 对象列表,代表所选主机以及任何备选主机。

备选方案

我们可以将 allocation_request 数据缓存在 placement 中,并仅返回资源提供程序以及一个键。 当需要进行声明时,将 POST 键而不是完整的 allocation_request 数据,并且 Placement 将使用缓存的数据来执行声明。 这种方法的优点是 Nova 侧的任何内容都不会使用 allocation_request 中的数据;对于 Nova 来说,它是一个不透明的 blob。 当然,缺点是 Placement 必须处理缓存。

我们可以将完整的 allocation_request 数据返回给调度器,然后在 Nova 侧处理缓存和密钥管理。 当需要声明/取消声明时,将从该缓存中检索 allocation_request 并 POST 到 placement。 这种替代方案不需要对 placement 进行任何更改,但要求 API 级别 cell 和所有本地 cell 都可以访问某种形式的“全局 RAM”缓存,该缓存可以在 cell 之间访问。

我们可以只返回一堆非结构化的 Python 数据,并在所有使用它的地方添加大量的注释,希望查看代码的任何人都能理解每个位代表什么,并且可以处理对数据进行的任何未来更改,而无需进行版本控制。

数据模型影响

不会对任何数据库模式进行更改,但这将引入一个新的版本控制对象。 该对象将包含以下字段及其类型

* compute_node_uuid: fields.UUIDField
* service_host: fields.StringField
* nodename: fields.StringField
* cell_uuid: fields.UUIDField
* numa_limits: fields.ObjectField("NUMATopologyLimits")
* allocation_request: fields.StringField

由于 allocation_request 值是一个复杂嵌套的结构,因此没有合适的字段类型,因此我们将它作为 JSON 表示形式存储在 StringField 中。 如本规范[2]中所述,allocation_request 的结构如下

"allocations": [
    {
        "resource_provider": {
            "uuid": $COMPUTE_NODE1_UUID
        },
        "resources": {
            "VCPU": $AMOUNT_REQUESTED_VCPU,
            "MEMORY_MB": $AMOUNT_REQUESTED_MEMORY_MB
        }
    },
    {
        "resource_provider": {
            "uuid": $SHARED_STORAGE_UUID
        },
        "resources": {
            "DISK_GB": $AMOUNT_REQUESTED_DISK_GB
        }
    },
]

REST API 影响

安全影响

通知影响

其他最终用户影响

性能影响

其他部署者影响

开发人员影响

这将使任何使用 Nova 代码库的人更容易,而无需解码复杂的数据结构,除此之外,没有其他任何作用。

实现

负责人

主要负责人

ed-leafe

其他贡献者

工作项

  • 创建 Selection 对象。

  • 修改调度器的 select_destinations() 方法,使用所选主机信息填充这些对象并返回它们。

依赖项

测试

这是 Queens 版本中进行的全面更改的一部分,所有这些都需要进行测试。 Selection 对象需要一些基本的测试,但大部分测试将在 conductor 中进行,以验证它是否适用于主机选择、资源声明以及构建失败时的重试。

文档影响

开发人员参考文档需要更新以记录这个新对象。 调度器工作流的文档也需要更新以反映这些更改。

参考资料

最初的问题在一篇博文中记录[0],然后在 Nova 调度器子团队会议[1]上进行了讨论,会议上同意了这种方法。

[0] https://blog.leafe.com/handling-unstructured-data/ [1] http://eavesdrop.openstack.org/meetings/nova_scheduler/2017/nova_scheduler.2017-08-28-14.00.log.html#l-140 [2] https://specs.openstack.org/openstack/nova-specs/specs/pike/approved/placement-allocation-requests.html

历史

修订版

发布名称

描述

Queens

引入