调试远程缓存命中以进行远程执行

<ph type="x-smartling-placeholder"></ph> 报告问题 <ph type="x-smartling-placeholder"></ph> 查看来源 每晚 · 7.2 条 · 7.1敬上 · 7.0 · 6.5 · 6.4

本页介绍了如何查看缓存命中率以及如何调查 缓存未命中的情况。

本页面假定您的构建和/或测试已成功完成, 采用远程执行方式,因此您需要确保 充分利用远程缓存

检查您的缓存命中率

在 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,后跟构建/测试 命令。

缓存命中问题排查

如果您没有获得预期的缓存命中率,请执行以下操作:

确保重新运行相同的构建/测试命令会生成缓存命中

  1. 运行您希望填充缓存的构建和/或测试。通过 首次在特定堆栈上运行新构建时, 缓存命中。作为远程执行的一部分,操作结果存储在 缓存,后续运行时应该会使用它们。

  2. 运行 bazel clean。此命令会清理您的本地缓存 以便调查远程缓存命中而不遮盖 本地缓存命中

  3. (在同一台计算机上)再次运行您调查的构建和测试 )。

  4. 检查 INFO 行上的缓存命中率。如果除了以下时间段内未看到任何进程: remote cache hitinternal,则表明您的缓存已正确填充, 。在这种情况下,请跳至下一部分。

  5. 造成差异的可能原因可能是 build 中某些非封闭因素导致 在两次运行中接收不同的操作键的操作。查找 执行以下操作:

    a. 重新运行相关的构建或测试以获取执行日志:

      bazel clean
      bazel --optional-flags build //your:target --execution_log_binary_file=/tmp/exec1.log
    

    b. 比较 运行两次。确保在两个日志文件中执行的操作相同。 差异可以揭示 。请更新您的 build 以消除这些差异。

    如果您能够解决缓存问题,并且现在重复运行 生成所有缓存命中,跳到下一部分。

    如果您的操作 ID 相同,但没有缓存命中, 阻止了缓存继续完成此部分, 检查是否存在常见问题。

  6. 检查执行日志中的所有操作是否将 cacheable 设置为 true。如果 cacheable 未显示在给定操作的执行日志中, 表示相应规则的no-cache 定义。BUILD查看mnemonictarget_label 执行日志中的 字段,以帮助确定执行操作的位置 。

  7. 如果操作相同且 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_cachedfalse,请确定其放置位置 设置为 false:可以在命令行或 bazelrc 文件。

确保跨机器进行缓存

在同一机器上按预期发生缓存命中后,运行 运行相同的 build/测试。如果您怀疑缓存 请执行以下操作:

  1. 请对构建稍作修改,以免影响现有缓存。

  2. 在第一台机器上运行 build:

     bazel clean
     bazel ... build ... --execution_log_binary_file=/tmp/exec1.log
    
  3. 在第二台机器上运行 build,确保在第 1 步中进行修改 包括:

     bazel clean
     bazel ... build ... --execution_log_binary_file=/tmp/exec2.log
    
  4. 比较两者的执行日志 。如果日志不完全相同,请检查您的 build 配置 以及因主机环境泄露导致的 添加到任一 build 中。

比较执行日志

执行日志包含在构建期间执行的所有操作的记录。对于 每个操作都有 SpawnExec 元素,其中包含来自操作键的所有信息。因此,如果 那么操作缓存键也完全相同。

如需比较未按预期共享缓存命中的两个构建的日志, 执行以下操作:

  1. 从每个构建获取执行日志,并将它们存储为 /tmp/exec1.log/tmp/exec2.log

  2. 下载 Bazel 源代码,然后使用以下命令导航到 Bazel 文件夹。您需要使用源代码来解析 包含 execlog 解析器

    git clone https://github.com/bazelbuild/bazel.git
    cd bazel
    
  3. 使用执行日志解析器将日志转换为文本。以下 调用还会对第二个日志中的操作进行排序,以匹配操作顺序 以方便比较。

    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
    
  4. 使用您喜爱的文本区分 /tmp/exec1.log.txt/tmp/exec2.log.txt