本页面介绍了如何在远程执行的上下文中检查缓存命中率,以及如何调查 缓存未命中。
本页面假定您有一个成功 利用远程执行的构建和/或测试,并且您希望确保有效地 利用远程缓存。
检查缓存命中率
在 Bazel 运行的标准输出中,查看列出
进程的 INFO 行,这些进程大致对应于 Bazel 操作。该行详细说明了操作的运行位置。
查找 remote 标签(表示远程执行的操作)、linux-sandbox(表示在本地沙盒中执行的操作)以及其他执行策略的其他值。结果来自远程缓存的操作显示为 remote cache hit。
例如:
INFO: 11 processes: 6 remote cache hit, 3 internal, 2 remote.
在此示例中,有 6 次远程缓存命中,并且有 2 个操作没有
缓存命中,而是远程执行的。可以忽略 3 内部部分。
它通常是微小的内部操作,例如创建符号链接。此摘要中不包含本地
缓存命中。如果您获得 0 个进程
(或低于预期数量),请运行 bazel clean,然后运行构建/测试
命令。
排查缓存命中问题
如果您未获得预期的缓存命中率,请执行以下操作:
确保重新运行相同的构建/测试命令会产生缓存命中
运行您希望填充缓存的构建和/或测试。首次在特定堆栈上运行新构建时,您可能不会获得远程 缓存命中。作为远程执行的一部分,操作结果会存储在 缓存中,后续运行应会提取这些结果。
运行
bazel clean。此命令会清理本地缓存,这样一来,您便可以在没有本地缓存命中的情况下调查远程缓存命中,而不会让结果被 本地缓存命中遮盖。再次(在同一台 机器上)运行要调查的构建和测试。
检查
INFO行中的缓存命中率。如果您只看到remote cache hit和internal进程,则表示您的缓存正在正确填充和 访问。在这种情况下,请跳到下一部分。差异的可能来源是构建中的某些非密封内容,导致 操作在两次运行中收到不同的操作键。如需查找 这些操作,请执行以下操作:
a. 重新运行有问题的构建或测试,以获取执行日志:
bazel cleanbazel --optional-flags build //your:target --execution_log_binary_file=/tmp/exec1.logb. 比较执行日志在 两次运行之间。确保操作在两个日志文件中是相同的。 差异提供了有关 运行之间发生的更改的线索。更新构建以消除这些差异。
如果您能够解决缓存问题,并且重复运行 现在会产生所有缓存命中,请跳到下一部分。
如果您的操作 ID 相同,但没有缓存命中,则表示您的配置中的某些内容 阻止了缓存。请继续阅读本部分,以 检查常见问题。
如果您不需要比较执行日志,则可以使用 人类可读的
--execution_log_json_file标志。它不能用于稳定的比较,因为它包含执行时间,并且不保证排序。检查执行日志中的所有操作是否都将
cacheable设置为 true。如果执行日志中未显示给定操作的cacheable,则表示相应规则的定义可能在 其 文件中的BUILD中包含no-cache标记。查看执行日志中人类可读的progress_message字段,以帮助确定操作的来源。如果操作相同且
cacheable,但没有缓存命中,则 可能是您的命令行包含--noremote_accept_cached,这 会停用构建的缓存查找。a. 将
--build_event_text_file=/tmp/bep.txt添加到 Bazel 命令中,以获取 日志的文本版本。b. 打开日志的文本版本,并搜索
structured_command_line消息,其中包含command_line_label: "canonical". 它将列出展开后的所有选项。c. 搜索
remote_accept_cached,并检查它是否设置为false。d. 如果
remote_accept_cached为false,请确定将其设置为false的位置:是在命令行中还是在 bazelrc 文件中。
确保跨机器缓存
在同一台机器上按预期发生缓存命中后,在另一台机器上运行 相同的构建/测试。如果您怀疑缓存未 跨机器发生,请执行以下操作:
对构建进行少量修改,以避免命中现有缓存。
在第一台机器上运行构建:
bazel cleanbazel ... build ... --execution_log_binary_file=/tmp/exec1.log在第二台机器上运行构建,确保包含第 1 步中的修改 :
bazel cleanbazel ... build ... --execution_log_binary_file=/tmp/exec2.log比较两次 运行的执行日志。如果日志不相同,请调查构建配置 是否存在差异,以及主机环境中的属性是否泄露 到任一构建中。
比较执行日志
执行日志包含构建期间执行的所有操作的记录。对于 每个操作,都有一个 SpawnExec 元素,其中包含操作键中的所有信息。因此,如果 日志相同,则操作缓存键也相同。
如需比较两个构建的日志(这两个构建未按预期共享缓存命中), 请执行以下操作:
从每个构建中获取执行日志,并将其存储为
/tmp/exec1.log和/tmp/exec2.log。下载 Bazel 源代码,然后使用 以下命令导航到 Bazel 文件夹。您需要源代码才能使用 execlog 解析器解析 执行日志。
git clone https://github.com/bazelbuild/bazel.git cd bazel使用执行日志解析器将日志转换为文本。以下 调用还会对第二个日志中的操作进行排序,以与第一个日志中的操作顺序匹配 ,以便于比较。
bazel build src/tools/execlog:parser bazel-bin/src/tools/execlog/parser \ --log_path=/tmp/exec1.log \ --log_path=/tmp/exec2.log \ --output_path=/tmp/exec1.log.txt \ --output_path=/tmp/exec2.log.txt使用您喜欢的文本比较工具比较
/tmp/exec1.log.txt和/tmp/exec2.log.txt。