可能每个 Bazel 用户都遇到了构建速度比预期慢或慢的情况。对具有重大影响的目标而言,提高个别 build 的性能具有特定的价值,例如:
经常迭代和(重新)构建的核心开发者目标。
其他目标广泛依赖的通用库。
利用一类目标(例如自定义规则)中的代表性目标,诊断和修复一个 build 中的问题可能有助于从更大规模的层面解决问题。
提高构建性能的一个重要步骤是了解资源的花费位置。本页面列出了您可以收集的不同指标。 细分 build 性能一文介绍了如何使用这些指标检测和修复 build 性能问题。
您可以通过几种主要方法从 Bazel 构建中提取指标,具体包括:
构建事件协议 (BEP)
Bazel 会通过构建事件协议 (BEP) 输出各种协议缓冲区 build_event_stream.proto
,这些缓冲区可以由您指定的后端进行汇总。根据您的用例,您可能会决定以各种方式聚合指标,但在这里,我们将介绍一些通常很有用的概念和 proto 字段。
Bazel 的 query / cquery / aquery 命令
Bazel 提供 3 种不同的查询模式(query、cquery 和 aquery),可让用户分别查询目标图、配置的目标图和操作图。查询语言提供了一套函数,这些函数可用于不同的查询模式,使您可以根据需要自定义查询。
JSON 跟踪配置文件
对于类似 build 的每次 Bazel 调用,Bazel 都会以 JSON 格式写入轨迹配置文件。JSON 跟踪记录配置文件有助于快速了解 Bazel 在调用过程中花了时间。
执行日志
执行日志可帮助您排查和修复由于机器和环境差异或非确定性操作而错失的远程缓存命中。如果您传递 --experimental_execution_log_spawn_metrics
标志(可在 Bazel 5.2 中获得),它还包含有关本地和远程执行的操作的详细生成指标。例如,您可以使用这些指标比较本地和远程机器的性能,或找出生成执行过程的哪个部分总是比预期慢(例如,由于出现排队情况)。
执行图日志
虽然 JSON 轨迹配置文件包含关键路径信息,但有时您还需要有关已执行操作的依赖关系图的更多信息。从 Bazel 6.0 开始,您可以传递 --experimental_execution_graph_log
和 --experimental_execution_graph_log_dep_type=all
标志,以写入关于所执行操作及其相互依赖项的日志。
此信息可用于了解关键路径上的节点添加的拖动。拖动量是指可通过从执行图中移除特定节点来节省的时间量。
这些数据可以帮助您在实际进行更改之前预测对 build 和操作图所做的更改的影响。
使用 bazel 长椅进行基准化分析
Bazel Bench 是一款基准化分析工具,供 Git 项目在以下情况下对 build 性能进行基准化分析:
项目基准:使用单个 Bazel 版本对两个 git 提交进行基准测试。用于检测 build 中的回归问题(通常通过添加依赖项来实现)。
Bazel 基准:在一次 git 提交中,对两个版本的 Bazel 进行基准测试。用于检测 Bazel 本身中的回归问题(如果您遇到了 Bazel 维护 / 分支问题)。
基准测试会监控实际用时、CPU 时间和系统时间和 Bazel 保留的堆大小。
此外,还建议在没有运行其他进程的专用物理机器上运行 Bazel Bench,以减少可变性来源。