Nova REST API 排序增强

https://blueprints.launchpad.net/nova/+spec/nova-pagination

目前,Nova 的分页支持不允许调用者指定数据集的排序顺序和方向。此蓝图增强了 /servers 和 /servers/detail API 的分页支持,以便可以在请求中提供多个排序键和排序方向。

问题描述

目前不支持以特定顺序检索服务器数据,默认按“创建日期”和“id”键降序排序。为了以任何排序顺序和方向检索数据,REST API 需要接受多个排序键和方向。

用例

一个 UI 显示一个表格,该表格仅显示从服务器检索到的数据页。此表格中的项目需要首先按状态排序,然后按显示名称排序。为了以这种顺序检索数据,API 必须接受多个排序键/方向。

项目优先级

目前没有设置优先级,但这属于用户体验范畴,因为它允许以自定义排序顺序检索数据。

提议的变更

/servers 和 /servers/detail API 将支持在请求中重复以下参数

  • sort_key: 用于确定排序顺序的键

  • sort_dir: 与关联排序键的方向(“asc”或“desc”)

调用者可以多次指定这些参数,以生成排序键和排序方向的列表。列出的第一个键是主键,下一个键是辅助键,依此类推。

例如:/servers?sort_key=status&sort_dir=desc&sort_key=display_name& &sort_dir=desc&sort_key=created_at&sort_dir=desc

注意:“created_at”和“id”排序键始终附加在键列表的末尾,如果它们尚未在请求中指定。

数据库层已经支持多个排序键和方向。此蓝图将更新 API 层以从 API 请求中检索排序信息,并将该信息传递到数据库层。

所有排序都在 sqlalchemy.utils.paginate_query 函数中处理。此函数接受一个 ORM 模型类作为参数,并且唯一的有效排序键是给定模型类上的属性。因此,有效的排序键仅限于 models.Instance 类上的模型属性。

对于 v2 API,将创建一个新的 ‘os-server-sort-keys’ API 扩展,以表明此蓝图提出的新的排序参数应被遵守。v3 API 将默认支持新的排序参数。

备选方案

选择重复参数键/值是因为 glance 已经这样做了

https://github.com/openstack/glance/blob/master/glance/api/v2/images.py#L526

但是,可以通过拆分关联的参数值来构建排序键和方向的列表。

例如:/servers?sort_key=status,display_name,created_at&sort_dir=desc,desc,desc

这种方法的缺点是它需要预定义的令牌字符。如果认为此解决方案更好,我很乐意接受。

数据模型影响

REST API 影响

将创建一个新的 v2 API 扩展,以表明新的排序参数应被遵守。扩展详细信息

  • 名称:ServerSortKeys

  • 别名:os-server-sort-keys

请注意,此 API 扩展的行为方式与当前的 ‘os-user-data’ 扩展相同。例如,扩展定义如下

http://git.openstack.org/cgit/openstack/nova/tree/nova/api/openstack/compute /contrib/user_data.py

它在此处检查 v2 服务器 API 中

http://git.openstack.org/cgit/openstack/nova/tree/nova/api/openstack/compute/ servers.py#n850

如果加载了 ‘os-server-sort-keys’ API 扩展,以下现有的 v2 GET API 将支持新的排序参数

  • /v2/{tenant_id}/servers

  • /v2/{tenant_id}/servers/detail

以下现有的 v3 GET API 将默认支持新的排序参数

  • /v3/servers

  • /v3/servers/details

请注意,此蓝图描述的设计可以应用于其他 GET REST API,但此蓝图的范围仅限于上述 API。一旦此设计完成,就可以将相同的方法应用于其他 API。

现有的 API 文档需要更新,以包含以下新的请求参数

参数

风格

类型

描述

sort_key

query

string

排序键(重复多次),键默认为 ‘created_at’ 和 ‘id’

sort_dir

query

string

排序方向,‘asc’ 或 ‘desc’(重复多次),默认为 ‘desc’

API 响应格式和返回码不会被修改,只会修改返回的服务器的顺序。

如果指定了无效的排序键,将返回一个“badRequest”错误响应(代码 400),并显示一条消息,例如“无效输入:无效的排序键”。

安全影响

通知影响

其他最终用户影响

novaclient 应更新为接受排序键和排序方向,新的参数

参数

描述

–sort-keys

逗号分隔的排序键列表,用于指定服务器排序。每个键必须与排序方向值配对。

–sort-dirs

逗号分隔的排序方向列表,用于指定服务器排序。每个键必须与排序键值配对。有效值为 ‘asc’ 和 ‘desc’。

性能影响

所有排序都在数据库中完成。排序键的选择仅限于 models.Instance ORM 类上的属性 – 不是从详细查询返回的每个属性键都是有效的排序键。

性能数据是通过在具有 2GB 内存的简单 devstack VM 上运行收集的。将 5000 个实例插入到 DB 中。数据显示,在运行详细查询时,主数据表上的排序时间被大大缩短(参见下表) – 大部分时间都花在查询其他表中的每个项目上;因此,排序键对详细查询的影响很小。

例如,下表比较了非详细查询的 GET 请求处理时间与使用默认排序键的各种限制的详细查询的处理时间。此表的目的在于显示详细查询的处理时间主要由获取每个项目的其他详细信息决定。

限制

非详细 (秒)

详细 (秒)

非详细 / 详细 %

50

0.0560

0.8621

6.5%

100

0.0813

1.6839

4.8%

150

0.0848

2.4705

3.4%

200

0.0874

3.2502

2.7%

250

0.0985

4.1237

2.4%

300

0.1229

4.8731

2.5%

350

0.1262

5.6366

2.2%

400

0.1282

6.5573

2.0%

450

0.1458

7.2921

2.0%

500

0.1770

8.1126

2.2%

1000

0.2589

16.0844

1.6%

还收集了非详细查询数据。下表比较了使用默认排序键与使用 display_name 作为排序键的处理时间。添加的项目具有 40 个字符的 display_name,该 display_name 以非字母顺序生成。

限制

默认键 (秒)

display_name 键 (秒)

减速 %

50

0.0560

0.0600

7.1%

100

0.0813

0.0832

2.3%

150

0.0848

0.0879

3.7%

200

0.0874

0.0906

3.7%

250

0.0985

0.1031

4.7%

300

0.1229

0.1198

-2.5%

350

0.1262

0.1319

4.5%

400

0.1282

0.1368

6.7%

450

0.1458

0.1458

0.0%

500

0.1770

0.1619

-8.5%

1000

0.2589

0.2659

2.7%

结论:主数据表上的排序处理对整体处理时间的影响很小。对于详细查询,排序时间被其他处理所掩盖 – 即使排序时间增加 3 倍,也仅代表详细查询中 4.8% 的总处理时间(限制为 1000)(并且仅将处理时间增加 0.11 秒,限制为 50)。

其他部署者影响

排序键的选择对数据检索性能的影响很小(参见上面的性能数据)。因此,应允许用户以他们需要的方式检索数据来创建他们的视图(参见问题描述中的用例)。

开发人员影响

实现

负责人

主要负责人

Steven Kaufer

其他贡献者

工作项

理想情况下,处理排序参数的逻辑应在所有组件中通用,并在 oslo 中完成;一个类似的蓝图也在 cinder 中提出:https://blueprints.launchpad.net/cinder/+spec/cinder-pagination

因此,我看到以下工作项目

  • 创建通用函数来处理 API 参数并创建排序键和方向的列表

  • 更新 v2 和 v3 API 以检索排序信息并传递到 DB 层(需要更改 compute/api.py、objects/instance.py、db/api.py 和 dbsqlalchemyapi.py)

  • 更新 novaclient 以接受和处理多个排序键和排序方向

依赖项

测试

需要创建单元和 Tempest 测试来确保数据以指定的排序顺序检索。测试还应验证默认排序键(“created_at”和“id”)始终附加到用户提供的键(如果用户尚未指定它们)。

应针对多种后端数据库类型进行测试。

文档影响

需要更新 /servers 和 /servers/detail API 文档以

  • 反映新的排序参数并解释这些参数将影响数据返回的顺序。

  • 解释默认排序键将始终添加到排序键列表的末尾

文档还可以指出查询性能会受到排序键选择的影响,并指出哪些键已编入索引。

参考资料