使用 Rally 在 Heat gates 上

Heat gate 允许为每个特定的补丁使用 Rally 进行性能测试。此功能可用于检查补丁的性能回归,并检测常见场景中的浮动错误。

如何为特定补丁运行 Rally

如上所述,Heat 允许将 Rally 场景作为特定补丁的 gate 任务执行。可以通过在 review 上发布带有文本 check experimental 的评论来完成。它将运行一系列任务,其中一个任务的名称为 gate-rally-dsvm-fakevirt-heat

将要执行的场景列表在文件 heat-fakevirt.yaml 中呈现。此文件的默认版本可在此处找到:https://github.com/openstack/heat/blob/2025.2/rally-scenarios/heat-fakevirt.yaml

显然,只有在可以与一些其他性能数据进行比较时,性能分析才有意义。因此,可以使用两种不同的方法:

使用 Rally 的示例

之前强调了两种主要的在 Heat 中使用 Rally job 的方法。本文档的这部分将描述相应的示例。

但是需要注意的是,还有许多其他方法可以使用 Rally job 进行 Heat 性能测试。例如,此 job 可以定期启动(每周两次)用于随机补丁,并且这些结果可以相互比较。这可以了解 Heat 是否存在任何性能回归。

检查性能或如何检测回归

使用 Rally 的最简单方法是执行现有的场景。一个示例在补丁 https://review.opendev.org/#/c/279450/ 中呈现。在此补丁中,执行了 Rally 中已存在的场景 HeatStacks.create_and_delete_stack。在执行此场景期间,Rally 会创建 Heat stack,然后在创建 stack 后删除它。所有现有场景都可以在这里找到:https://github.com/openstack/rally-openstack/blob/2025.2/rally_openstack/scenarios/heat/stacks.py

提到的场景使用 Heat 模板作为任务的参数。应为参数 template_path 提及模板路径。它可以是 Rally 存储库中呈现的 Heat 模板之一 (https://github.com/openstack/rally-openstack/tree/2025.2/samples/tasks/scenarios/heat/templates) 或新的模板,就像在提到的补丁中所做的那样。新添加的模板应放置在 rally-scenarios/extra/ 目录中。

也可以为每个 Rally 任务指定其他字段,例如 slacontext。有关其他配置设置的更多信息,请访问链接 https://rally.readthedocs.io/en/2025.2/plugins/#rally-plugins 提到的补丁是为确认 Heat 模板验证过程的缓存机制而提出的(参见 https://specs.openstack.org/openstack/heat-specs/specs/2025.2/constraint-validation-cache.html)。因此,它包含 OS::Heat::TestResource 资源中的一些更改,这可以展示上述缓存功能改进。

最初,测试是在当前的 devstack 安装上运行的,在该安装上禁用了缓存(例如,Patch Set 7)。获得的结果如下

行动

最小值 (秒)

最大值 (秒)

平均值 (秒)

成功

计数

heat.create_stack

38.223

48.085

42.971

100.0%

10

heat.delete_stack

11.755

18.155

14.085

100.0%

10

total

50.188

65.361

57.057

100.0%

10

在下一个补丁集中(Patch Set 8),通过在提交消息中添加 Depends-On 引用来更新。它允许使用启用缓存的 devstack 执行相同的测试 (https://review.opendev.org/#/c/279400/)。此情况的结果是

行动

最小值 (秒)

最大值 (秒)

平均值 (秒)

成功

计数

heat.create_stack

11.863

16.074

14.174

100.0%

10

heat.delete_stack

9.144

11.663

10.595

100.0%

10

total

21.557

27.18

24.77

100.0%

10

将首次和第二次执行中 create_stack 操作的平均值进行比较表明,启用缓存后,create_stack 的速度提高了 3 倍。这是 create_stack 操作的显著改进。需要注意的是,在描述的测试中,每个约束验证请求的延迟为 0.3 秒,如 TestResource 的 constraint_prop_secs 属性中所指定。这可能比实际延迟时间长,但它可以确认缓存正常工作。

这种方法也可以用于检测回归。在这种情况下,工作流程可以表示为以下步骤列表:

  • 将现有或新任务添加到任务列表 (heat-fakevirt.yaml)。

  • 等待本次执行的结果。

  • 上传带有更改(新功能)的补丁集,然后再次启动相同的测试。

  • 比较性能结果。

比较输出 API 性能

使用 Rally job 的另一个示例是在 Heat 存储库中编写自定义 Rally 场景。review 上有一个示例:https://review.opendev.org/#/c/270225/

它类似于第一个示例,但需要更多的 Rally 特定编码。 heat-fakevirt.yaml 中的新任务使用 Rally 存储库中未定义的场景

  • CustomHeatBenchmark.create_stack_and_show_output_new

  • CustomHeatBenchmark.create_stack_and_show_output_old

  • CustomHeatBenchmark.create_stack_and_list_output_new

  • CustomHeatBenchmark.create_stack_and_list_output_old

所有这些场景都定义在同一个补丁中,并放置在 rally-scenarios/plugins/ 目录中。

这些场景和任务的目的是演示新旧 API 调用的差异。Heat 客户端有两个命令用于操作 stack 输出:heat output-listheat output-show <output-id>。 之前没有特殊的 API 调用来从服务器获取此信息,并且此数据是从整个 Heat Stack 对象获得的。在实现新的输出 API 后,这发生了变化:https://specs.openstack.org/openstack/heat-specs/specs/2025.2/api-calls-for-output.html

如上述规范所述,可以通过向 Heat API 发出特殊请求来获取输出。根据这些更改,Heat 客户端中的代码已更新为在可用时使用新的 API。

此更改的最初问题是性能问题,可以表述为:使用旧方法执行命令 heat output-show <output-id> 需要先解析 Heat Stack 中的所有输出,然后才能获取用户指定的单个输出。

对于 heat output-list,也是如此,它需要解析所有输出才能仅提供输出键的列表,而无需解析值。

带有后缀 *_new 的场景使用新的输出 API。这些场景尚未在 Rally 中呈现,因为它是新的 API。带有后缀 *_old 的另两个场景基于获取输出的旧方法。此代码已被新的 API 部分替换,因此无法在新的 devstack 上使用它。因此,此自定义代码被编写为两个自定义场景。

所有这些场景都已添加到任务列表中并同时执行。执行结果如下

create_stack_and_show_output_old

行动

最小值 (秒)

最大值 (秒)

平均值 (秒)

成功

计数

heat.create_stack

13.559

14.298

13.899

100.0%

5

heat.show_output_old

5.214

5.297

5.252

100.0%

5

heat.delete_stack

5.445

6.962

6.008

100.0%

5

total

24.243

26.146

25.159

100.0%

5

create_stack_and_show_output_new

行动

最小值 (秒)

最大值 (秒)

平均值 (秒)

成功

计数

heat.create_stack

13.719

14.286

13.935

100.0%

5

heat.show_output_new

0.699

0.835

0.762

100.0%

5

heat.delete_stack

5.398

6.457

5.636

100.0%

5

total

19.873

21.21

20.334

100.0%

5

使用旧方法的执行 output-show 的平均值显然高于新 API。这是因为新的 API 仅解析指定的单个输出。

对于 output-list 也是如此

create_stack_and_list_output_old

行动

最小值 (秒)

最大值 (秒)

平均值 (秒)

成功

计数

heat.create_stack

13.861

14.573

14.141

100.0%

5

heat.list_output_old

5.247

5.339

5.281

100.0%

5

heat.delete_stack

6.727

6.845

6.776

100.0%

5

total

25.886

26.696

26.199

100.0%

5

create_stack_and_list_output_new

行动

最小值 (秒)

最大值 (秒)

平均值 (秒)

成功

计数

heat.create_stack

13.902

21.117

16.729

100.0%

5

heat.list_output_new

0.147

0.363

0.213

100.0%

5

heat.delete_stack

6.616

8.202

7.022

100.0%

5

total

20.838

27.908

23.964

100.0%

5

这也是预期的,因为获取输出名称列表不需要解析值,就像在新的 API 中所做的那样。

所有上述结果清楚地显示了性能变化,并允许确认新的方法有效。