返回选择对象¶
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 |
引入 |