<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>BuildBuddy on 翟志军 Jack Zhai</title>
    <link>https://showme.codes/tags/buildbuddy/</link>
    <description>Recent content in BuildBuddy on 翟志军 Jack Zhai</description>
    <generator>Hugo</generator>
    <language>en-us</language>
    <copyright>showme.codes</copyright>
    <lastBuildDate>Mon, 09 Nov 2026 09:30:12 +0800</lastBuildDate>
    <atom:link href="https://showme.codes/tags/buildbuddy/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>[译] 我的 Bazel 构建为什么这么慢？</title>
      <link>https://showme.codes/zh-cn/buildbuddy-debugging-slow-bazel-builds/</link>
      <pubDate>Mon, 09 Nov 2026 09:30:12 +0800</pubDate>
      <guid>https://showme.codes/zh-cn/buildbuddy-debugging-slow-bazel-builds/</guid>
      <description>从构建 flags、analysis cache、JVM 内存、action cache 和构建趋势入手，结合 timing profile 排查 Bazel 构建变慢的原因。</description>
    </item>
    <item>
      <title>[译] Action Merging</title>
      <link>https://showme.codes/zh-cn/buildbuddy-action-merging/</link>
      <pubDate>Mon, 09 Nov 2026 08:00:59 +0800</pubDate>
      <guid>https://showme.codes/zh-cn/buildbuddy-action-merging/</guid>
      <description>&lt;p&gt;原文：&lt;a href=&#34;https://www.buildbuddy.io/blog/action-merging&#34;&gt;Action Merging&lt;/a&gt;&lt;br&gt;
作者：Iain Macdonald · 原文发表于 2026-01-05。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;译注：文中的“我们”指原作者或 BuildBuddy 团队，时效性表述以原文发布日期为准。Bazel 专有名词保留英文，代码和命令未作翻译。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;BuildBuddy 的 remote execution 引擎会合并相同 actions 尚未完成的执行，为用户节省时间和资源。本文会介绍 action merging 为什么有用、具体如何实现，以及我们多年来在生产环境中积累的经验。&lt;/p&gt;
&lt;h2 id=&#34;overview&#34;&gt;概述&lt;/h2&gt;
&lt;p&gt;缓存 action 结果是 Bazel 的核心性能优化之一。但本地缓存和 remote Bazel 缓存都不能共享尚未完成的执行结果。比如，Alice 提交一项后端改动，需要运行 BigSlowTest。测试尚未结束，Bob 又提交一处很小的前端改动，Bob 仍得重新运行同一个 BigSlowTest。这会拖慢他的 invocation，还可能重复消耗模拟器许可证或配额等外部资源。&lt;/p&gt;
&lt;p&gt;&lt;img loading=&#34;lazy&#34; src=&#34;https://showme.codes/images/buildbuddy/action-merging-timeline-db317991b5cb4158ab144023d7aa4a82-57a3227bed17.webp&#34;&gt; &lt;em&gt;A Alice 和 Bob 未合并的 BigSlowTest 执行的时间线。&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;这个例子并不只是设想。下文介绍的 action merging 系统，在生产高峰期每秒会合并超过 1,000 个 actions，为某些长时间运行的测试节省接近 3 小时。Stripe 也曾在&lt;a href=&#34;https://stripe.com/blog/fast-secure-builds-choose-two&#34;&gt;这篇文章&lt;/a&gt;中介绍过他们解决同类问题的内部方案。&lt;/p&gt;
&lt;h2 id=&#34;background&#34;&gt;背景&lt;/h2&gt;
&lt;h3 id=&#34;actions-and-executions&#34;&gt;Actions 和执行&lt;/h3&gt;
&lt;p&gt;Actions 是 Bazel 的工作单元，作为更大的 invocation 的一部分运行。 action 可能是编译或链接命令。每个 action 都有一个 ID，称为 Action ID，它是 action 的定义（命令、环境变量）和所有输入的哈希值。&lt;/p&gt;</description>
    </item>
    <item>
      <title>[译] Remote Cache CDC：复用已有字节</title>
      <link>https://showme.codes/zh-cn/buildbuddy-content-defined-chunking/</link>
      <pubDate>Mon, 09 Nov 2026 08:00:59 +0800</pubDate>
      <guid>https://showme.codes/zh-cn/buildbuddy-content-defined-chunking/</guid>
      <description>&lt;p&gt;原文：&lt;a href=&#34;https://www.buildbuddy.io/blog/content-defined-chunking&#34;&gt;Remote Cache CDC: Reusing Bytes&lt;/a&gt;&lt;br&gt;
作者：Tyler French · 原文发表于 2026-05-01。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;译注：文中的“我们”指原作者或 BuildBuddy 团队，时效性表述以原文发布日期为准。Bazel 专有名词保留英文，代码和命令未作翻译。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;img alt=&#34;在复用内容中添加新内容&#34; loading=&#34;lazy&#34; src=&#34;https://showme.codes/images/buildbuddy/cdc_intro_image-55b6ee3b10bfcb49674777c8cb158d82-9bf81dd8269d.jpg&#34;&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;目标：移动更改的字节，而不是整个输出。&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;BuildBuddy 的 Remote Cache 使用内容定义分块（CDC），让大型构建输出也能按增量传输。如果二进制文件、bundle、package 或归档文件的大部分内容未变，BuildBuddy 就能复用已经保存的 chunks，无需重新上传或下载整个文件。&lt;/p&gt;
&lt;p&gt;在&lt;a href=&#34;https://github.com/bazelbuild/bazel/pull/28437&#34;&gt;为 Bazel 实现缓存分块的 PR&lt;/a&gt;中，我们对 BuildBuddy 自己的代码库做了基准测试，观察到上传数据量减少 40%，disk cache 体积也减小了 40%。要在 BuildBuddy 上启用客户端 CDC，请使用 Bazel 8.7 或 9.1+，并传入 &lt;code&gt;--experimental_remote_cache_chunking&lt;/code&gt;。&lt;/p&gt;
&lt;h2 id=&#34;setting-the-scene&#34;&gt;背景&lt;/h2&gt;
&lt;p&gt;构建缓存下一步要减少的，不只是需要执行的 actions，还有需要传输的字节。&lt;/p&gt;
&lt;p&gt;构建 缓存已经取得了长足的进步。 Bazel 和 remote caching 允许团队在机器和 CI 作业中重复使用 action 输出，而不是在每次编辑后重建世界。在实践中，构建已经从接近 O（存储库大小）转向 O（变更大小）。&lt;/p&gt;
&lt;p&gt;不过，“改动大小”可能会产生误导。真正重要的是，这次编辑影响到的传递性 actions 有多大。即使各个输出实际改变的都只是一小部分，一处很小的源代码修改仍可能波及许多二进制文件、package、bundle 和其他大型输出。&lt;/p&gt;
&lt;p&gt;这类缓存失效符合预期：构建系统在输入变化时，本来就应重新运行 action。remote cache 的问题出在后续传输上。即使 blob 的大部分字节都和上一版一样，只要摘要变化，缓存仍会传输整个 blob。&lt;/p&gt;
&lt;h2 id=&#34;transitive-actions&#34;&gt;传递式 Actions&lt;/h2&gt;
&lt;p&gt;链接、捆绑、打包和归档是最常出现的情况。它们将许多传递输入组合成一个输出。&lt;/p&gt;</description>
    </item>
    <item>
      <title>[译] Snapshot、Chunk、Clone：大规模部署快速 runner</title>
      <link>https://showme.codes/zh-cn/buildbuddy-fast-runners-at-scale/</link>
      <pubDate>Mon, 09 Nov 2026 08:00:59 +0800</pubDate>
      <guid>https://showme.codes/zh-cn/buildbuddy-fast-runners-at-scale/</guid>
      <description>&lt;p&gt;原文：&lt;a href=&#34;https://www.buildbuddy.io/blog/fast-runners-at-scale&#34;&gt;Snapshot, Chunk, Clone: Fast Runners at Scale&lt;/a&gt;&lt;br&gt;
作者：Maggie Lou · 原文发表于 2026-01-26。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;译注：文中的“我们”指原作者或 BuildBuddy 团队，时效性表述以原文发布日期为准。Bazel 专有名词保留英文，代码和命令未作翻译。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;在 BuildBuddy，我们的核心使命是加快构建速度。我们使用 Firecracker 快照来按需保持预热 workers 的可用性。&lt;/p&gt;
&lt;p&gt;只需一个curl请求，您就可以在warm worker中运行任何bash命令。&lt;/p&gt;
&lt;h2 id=&#34;painting-the-scene&#34;&gt;背景&lt;/h2&gt;
&lt;p&gt;想象一下，每天早上您都必须从头开始重新初始化笔记本电脑上的开发环境，重新安装工具并克隆 git 存储库。接着还得下载容器映像并启动各种应用程序。一想到这些时间和精力我就感到不寒而栗。&lt;/p&gt;
&lt;p&gt;不仅设置会很慢，而且所有初始工作负载也会更慢。应用程序和内核必须重新填充各种内存和磁盘缓存，并下载工具和依赖项。&lt;/p&gt;
&lt;p&gt;Cold start 是计算系统中常见的问题。GitHub Actions 等 CI 平台会为每次任务初始化新的 worker，AI 编程 agent 也通常运行在尚未预热的 cold runners 上。这样能让环境保持干净、一致，并与其他客户的任务隔离，但每次任务也往往需要多花几分钟。&lt;/p&gt;
&lt;p&gt;借助可创建 snapshot 的 runners，只需承担一次初始化 cold worker 的耗时，后续任务就能直接克隆已经预热的 worker。&lt;/p&gt;
&lt;p&gt;这些 workers 具有许多有价值的特性：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;灵活性&lt;/strong&gt;：每个worker都有自己的内核，提高安全性并支持需要Docker或自定义映像的复杂工作负载。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;写入时复制&lt;/strong&gt;：可以从共享基线克隆并行workers，同时在写入时复制更改，从而允许不同的工作负载运行而不会产生干扰。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;可扩展性&lt;/strong&gt;：能通过网络克隆，为我们提供可持续扩展的快速 runners 集群。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;持久性&lt;/strong&gt;：可以保存到磁盘，让 workers 在机器重启或自动伸缩后仍能恢复。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;高容量&lt;/strong&gt;：可以处理需要高达100GB磁盘和大量内存的大型工作负载，这对于单一存储库或运行ML模型等内存密集型任务通常是必需的。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;增量更新&lt;/strong&gt;：可以随着每个工作负载进行增量更新，从而减少环境偏差，甚至在数周的开发过程中也是如此。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;内存持久性&lt;/strong&gt;：可以跨工作负载保留内存中状态，允许重复使用昂贵的初始化工作（例如Bazel的分析图和JVM堆状态）。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;在我们的代码库中，一次完全命中缓存的 Bazel 构建 大约需要 6 分钟。在 GitHub Actions 上，初始化 worker 就要花 3.5 分钟，包括安装工具、对 GitHub repository 做 sparse checkout，以及在 构建 开始前生成 Bazel 的 analysis graph。这意味着，仅准备工作就占了 CI 时间的三分之一以上！&lt;/p&gt;</description>
    </item>
    <item>
      <title>[译] 使用 Podman 和 SOCI Snapshotter 按需拉取容器镜像</title>
      <link>https://showme.codes/zh-cn/buildbuddy-image-streaming/</link>
      <pubDate>Mon, 09 Nov 2026 08:00:59 +0800</pubDate>
      <guid>https://showme.codes/zh-cn/buildbuddy-image-streaming/</guid>
      <description>&lt;p&gt;原文：&lt;a href=&#34;https://www.buildbuddy.io/blog/image-streaming&#34;&gt;Lazily Pulling Container Images with Podman and SOCI Snapshotter&lt;/a&gt;&lt;br&gt;
作者：Iain Macdonald · 原文发表于 2023-11-15。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;译注：文中的“我们”指原作者或 BuildBuddy 团队，时效性表述以原文发布日期为准。Bazel 专有名词保留英文，代码和命令未作翻译。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;译注：缓存淘汰一节原文末句中的“only require re-indexing except after”疑有笔误。结合上文关于缓存访问与淘汰的说明，本译文将其理解为：经常使用的镜像通常只在容器 registry 中更新后才需要重新建立索引。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;我们很高兴地宣布 podman 的性能改进，使在 BuildBuddy 的托管执行服务上拉取容器镜像的速度提高了约十倍，减少了客户 构建 和测试时间，并提高了我们自动扩展 BuildBuddy executor 池的能力。请继续阅读以了解具体细节。&lt;/p&gt;
&lt;h2 id=&#34;containerization&#34;&gt;容器化&lt;/h2&gt;
&lt;p&gt;在 BuildBuddy，我们使用容器来隔离 actions 并支持在我们托管的 remote execution 服务上执行任意代码。在生产中，我们使用 Podman 作为默认容器运行时，但我们也支持 Docker 和 Firecracker。我们在容器设置中遇到的一个重大挑战是，在 cold 启动后拉取容器镜像可能会非常慢。我们的 executor 镜像约为 1 GB，在我们的 GCP 生产环境中提取它们通常需要大约 30 秒的时间。一些客户提供的镜像超过 10GB，并且可能需要几分钟的时间来拉取和提取。&lt;/p&gt;
&lt;p&gt;显着的镜像拉取延迟不仅会直接减慢客户的构建和测试速度，还会限制我们自动扩展 executor 池和响应重负载的能力。当新的 BuildBuddy executors 启动时，它们会根据需要拉取容器镜像。这意味着 executor 首次运行使用某镜像的 action 时，要先等待镜像拉取。队列中使用同一镜像的其他 actions 也会被阻塞。因此，我们提取容器镜像的速度越快，我们就能更快地启动新的 executors 并开始运行客户提交的 actions。我们可以通过始终运行更多的 executors 来解决这个问题，或者在高峰时段抢先扩展 executor 池，但这些技巧最多只能部分解决这个问题，并且还有其他缺点。&lt;/p&gt;</description>
    </item>
    <item>
      <title>[译] 我们如何用 ClickHouse 分析数百万次构建的趋势</title>
      <link>https://showme.codes/zh-cn/buildbuddy-clickhouse-build-trends/</link>
      <pubDate>Mon, 09 Nov 2026 08:00:59 +0800</pubDate>
      <guid>https://showme.codes/zh-cn/buildbuddy-clickhouse-build-trends/</guid>
      <description>&lt;p&gt;原文：&lt;a href=&#34;https://www.buildbuddy.io/blog/clickhouse-build-trends&#34;&gt;How We Use ClickHouse to Analyze Trends Across Millions of Builds&lt;/a&gt;&lt;br&gt;
作者：Lulu Zhang · 原文发表于 2022-11-22。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;译注：文中的“我们”指原作者或 BuildBuddy 团队，时效性表述以原文发布日期为准。Bazel 专有名词保留英文，代码和命令未作翻译。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;使用 Buildbuddy 配合 Bazel 构建、测试软件时，Buildbuddy 会记录每次 Bazel invocation 的信息，包括构建次数、构建耗时和 remote cache 性能等。Buildbuddy 的 &lt;a href=&#34;https://app.buildbuddy.io/trends/&#34;&gt;Trends&lt;/a&gt; 页面会把这些数据随时间的变化展示出来。&lt;/p&gt;
&lt;p&gt;&lt;img loading=&#34;lazy&#34; src=&#34;https://showme.codes/images/buildbuddy/trends-2-bbbcae75b1991b8423e69b75df0952d8-1d9e9282bb2c.png&#34;&gt;&lt;/p&gt;
&lt;p&gt;趋势页面能帮助你判断，所做的优化如何影响平均构建耗时及其他指标，也能暴露待改进的地方。比如，cache hit 率持续下降，可能是构建中存在结果不确定的构建 actions，也可能是新引入的依赖使缓存更频繁地失效。&lt;/p&gt;
&lt;p&gt;当我们第一次创建趋势页面时，我们使用 MySQL 查询来聚合 构建 统计数据并生成我们想要显示的数据。有一段时间，这种方法效果很好，但我们很快就遇到了拥有大量构建的客户的性能问题。我们能够通过添加各种索引来暂时提高性能，尽管这有助于减少读取的行数，但这还不够。有些客户每月进行数百万次构建，这些客户的“趋势”页面（可以追溯到一年）需要超过 20 &lt;em&gt;分钟&lt;/em&gt; 的加载时间。&lt;/p&gt;
&lt;p&gt;趋势页面背后的查询需要多列的聚合，例如cache hits和cache misses。像 MySQL 这样的传统的基于行的数据库并不总是适合这种用例。在基于行的数据库中，数据是逐行存储的。聚合列时，比基于列的数据库需要更多的 I/O 查找，基于列的数据库将每列的数据存储在连续的块中。此外，基于列的数据库具有更高的压缩率，因为同一列的连续值具有相同的类型并且可能重复。&lt;/p&gt;
&lt;p&gt;&lt;img loading=&#34;lazy&#34; src=&#34;https://showme.codes/images/buildbuddy/row-column-datastore-599977fd97a8b05de1e4267f50ac9f25-2a890150d8ff.png&#34;&gt;&lt;/p&gt;
&lt;p&gt;对于基于行的存储，我们可以从该图中看到，计算 cache hit 计数的总和需要我们加载块 1 和块 2。对于基于列的存储，所有 cache hits 数据都存储在同一块中。&lt;/p&gt;
&lt;p&gt;因此，我们认为使用 ClickHouse（基于列的数据库）将提高趋势页面所需查询的性能。我们根据我们的用例验证了 ClickHouse 的性能：ClickHouse 处理 150 万行并计算统计数据花了 0.317 秒。相同的查询花费了 MySQL 大约 24 分钟。&lt;/p&gt;</description>
    </item>
    <item>
      <title>[译] 理解 Bazel 的 Remote Caching 与 Remote Execution</title>
      <link>https://showme.codes/zh-cn/buildbuddy-bazels-remote-caching-and-remote-execution-explained/</link>
      <pubDate>Mon, 09 Nov 2026 08:00:59 +0800</pubDate>
      <guid>https://showme.codes/zh-cn/buildbuddy-bazels-remote-caching-and-remote-execution-explained/</guid>
      <description>&lt;p&gt;原文：&lt;a href=&#34;https://www.buildbuddy.io/blog/bazels-remote-caching-and-remote-execution-explained&#34;&gt;Bazel&amp;rsquo;s Remote Caching and Remote Execution Explained&lt;/a&gt;&lt;br&gt;
作者：Brentley Jones · 原文发表于 2022-03-16。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;译注：文中的“我们”指原作者或 BuildBuddy 团队，时效性表述以原文发布日期为准。Bazel 专有名词保留英文，代码和命令未作翻译。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;译注：本文的 flag 名称和默认行为对应写作时的 Bazel 5.0；相关文档与代码链接也指向该版本。文中保留这些历史名称，以便与原文的执行流程和脚注对应。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Bazel 著名的 remote caching 和 remote execution 功能可以改变游戏规则，但如果您不熟悉它们的工作原理，它们可能会有点神秘。&lt;/p&gt;
&lt;p&gt;别担心。我会从基础讲起，介绍 remote caching 和 remote execution，再深入到具体细节，也就是 actions 和 spawns 😄，带你了解 Bazel 的远程能力。&lt;/p&gt;
&lt;h2 id=&#34;actions&#34;&gt;Actions&lt;/h2&gt;
&lt;p&gt;对于一次请求的 构建，&lt;a href=&#34;https://docs.bazel.build/versions/5.0.0/glossary.html#build-graph&#34;&gt;构建 graph&lt;/a&gt; 中的每个 &lt;a href=&#34;https://docs.bazel.build/versions/5.0.0/glossary.html#rule&#34;&gt;rule target&lt;/a&gt;，都会在 &lt;a href=&#34;https://docs.bazel.build/versions/5.0.0/glossary.html#analysis-phase&#34;&gt;analysis phase&lt;/a&gt; 生成零个或多个 &lt;a href=&#34;https://docs.bazel.build/versions/5.0.0/glossary.html#action&#34;&gt;actions&lt;/a&gt;。这些 actions 组成 &lt;a href=&#34;https://docs.bazel.build/versions/5.0.0/glossary.html#action-graph&#34;&gt;action graph&lt;/a&gt;，表示 &lt;a href=&#34;https://docs.bazel.build/versions/5.0.0/glossary.html#execution-phase&#34;&gt;execution phase&lt;/a&gt; 期间需要执行的全部 actions。&lt;/p&gt;
&lt;p&gt;&lt;img loading=&#34;lazy&#34; src=&#34;https://showme.codes/images/buildbuddy/action-graph-baae4ebd49d1df74b6f39951baa33250-37424f94fecc.svg&#34;&gt;&lt;/p&gt;
&lt;p&gt;示例 action graph。 Actions 按创建它们的 targets 进行分组。箭头连接 actions，显示它们之间的依赖关系。&lt;/p&gt;
&lt;p&gt;在 execution phase，Bazel 会遍历 action graph，逐个判断 action 是否需要执行。如果 output base 的 &lt;a href=&#34;https://docs.bazel.build/versions/5.0.0/glossary.html#action-cache&#34;&gt;action cache&lt;/a&gt; 中没有对应的 &lt;a href=&#34;https://github.com/bazelbuild/bazel/blob/5.0.0/src/main/java/com/google/devtools/build/lib/actions/ActionResult.java#L26-L28&#34;&gt;action 结果&lt;/a&gt;，或者 &lt;a href=&#34;https://docs.bazel.build/versions/5.0.0/glossary.html#output-base&#34;&gt;output base&lt;/a&gt; 中的输出与 action 结果记录的输出不一致，就需要执行。&lt;/p&gt;</description>
    </item>
    <item>
      <title>[译] 用 Git Bisect 排查 Bazel 构建问题</title>
      <link>https://showme.codes/zh-cn/buildbuddy-bisect-bazel/</link>
      <pubDate>Mon, 09 Nov 2026 08:00:59 +0800</pubDate>
      <guid>https://showme.codes/zh-cn/buildbuddy-bisect-bazel/</guid>
      <description>&lt;p&gt;原文：&lt;a href=&#34;https://www.buildbuddy.io/blog/bisect-bazel&#34;&gt;Troubleshooting Bazel with Git Bisect&lt;/a&gt;&lt;br&gt;
作者：Son Luong Ngoc · 原文发表于 2025-02-18。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;译注：文中的“我们”指原作者或 BuildBuddy 团队，时效性表述以原文发布日期为准。Bazel 专有名词保留英文，代码和命令未作翻译。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;译注：本文保留 2025 年 2 月使用 Bazel 8.0.1、8.1.0 和 rules_go 排查回归的案例。版本号、commit 和日志均是当时的记录，用来演示二分定位方法。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;升级 Bazel 和相关依赖项有时会导致意外问题。这些问题的范围从 构建 故障到运行时错误，而且通常很难排除故障。&lt;/p&gt;
&lt;p&gt;今天我们来看看，依赖升级后出现 构建 失败，如何用 &lt;code&gt;git bisect&lt;/code&gt; 找出根因。&lt;/p&gt;
&lt;h2 id=&#34;build-failed-after-upgrading-bazel&#34;&gt;升级 Bazel 后 构建 失败&lt;/h2&gt;
&lt;p&gt;如果您像我一样，您会喜欢在项目中拥有最新、最好的工具。而我使用最多的工具是Bazel，所以随着最近&lt;code&gt;8.1.0&lt;/code&gt;版本的发布，我决定升级我们的BuildBuddy repository来使用它。&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;$ &lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;8.1.0&amp;#39;&lt;/span&gt; &amp;gt; .bazelversion
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;$ bazel &lt;span class=&#34;nb&#34;&gt;test&lt;/span&gt; --config&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;remote-minimal //...
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;...
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;ERROR: /root/workspace/output-base/external/bazel_tools/tools/build_defs/repo/http.bzl:137:45: An error occurred during the fetch of repository &lt;span class=&#34;s1&#34;&gt;&amp;#39;rules_cc+&amp;#39;&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   Traceback &lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;most recent call last&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        File &lt;span class=&#34;s2&#34;&gt;&amp;#34;/root/workspace/output-base/external/bazel_tools/tools/build_defs/repo/http.bzl&amp;#34;&lt;/span&gt;, line 137, column 45, in _http_archive_impl
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                &lt;span class=&#34;nv&#34;&gt;download_info&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; ctx.download_and_extract&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Error in download_and_extract: com.google.devtools.build.lib.remote.common.CacheNotFoundException: Missing digest: abc605dd850f813bb37004b77db20106a19311a96b2da1c92b789da529d28fe1/178823
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;...
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;哎呀！将 Bazel 升级到 &lt;code&gt;8.1.0&lt;/code&gt; 后，构建 似乎失败了。返回到 &lt;code&gt;8.0.1&lt;/code&gt; 问题就消失了，这意味着问题是在 Bazel &lt;code&gt;8.1.0&lt;/code&gt; 中引入的。&lt;/p&gt;</description>
    </item>
    <item>
      <title>[译] 通过分布式调度加快构建</title>
      <link>https://showme.codes/zh-cn/buildbuddy-distributed-scheduling-for-faster-builds/</link>
      <pubDate>Mon, 09 Nov 2026 08:00:59 +0800</pubDate>
      <guid>https://showme.codes/zh-cn/buildbuddy-distributed-scheduling-for-faster-builds/</guid>
      <description>&lt;p&gt;原文：&lt;a href=&#34;https://www.buildbuddy.io/blog/distributed-scheduling-for-faster-builds&#34;&gt;Distributed Scheduling for Faster Builds&lt;/a&gt;&lt;br&gt;
作者：Tyler Williams · 原文发表于 2022-04-07。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;译注：文中的“我们”指原作者或 BuildBuddy 团队，时效性表述以原文发布日期为准。Bazel 专有名词保留英文，代码和命令未作翻译。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;先向还不了解的读者介绍一下 BuildBuddy。我们为 Bazel 构建提供 UI、分布式缓存和 remote execution 平台，安全地编译代码、缓存 artifacts，并展示结果。使用这套服务，可以在笔记本上用不到 5 分钟构建 Tensorflow 等项目，而原先需要 90 分钟。&lt;/p&gt;
&lt;p&gt;显然，要做到这一切，我们必须应对一些棘手的工程挑战，其中之一就是安排远程执行。为此，我们有一个调度程序。调度程序只是将我们的 API 接收到的 actions（基本上是作业）与实际执行工作的远程 workers 相匹配。如果您将 Tensorflow 之类的完整 构建 视为 10 道菜的餐食，那么单个 action 就相当于该餐食一小部分的食谱。为了更容易可视化，这里有一个来自构建 BuildBuddy 的真实 action：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# this action just uses gcc to compile zlib/infback.c into an object file, zlib/infback.o&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;/usr/bin/gcc -U_FORTIFY_SOURCE -fstack-protector -Wall -Wunused-but-set-parameter &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  -Wno-free-nonheap-object -fno-omit-frame-pointer -g0 -O2 -D_FORTIFY_SOURCE&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;m&#34;&gt;1&lt;/span&gt; &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  -DNDEBUG -ffunction-sections -fdata-sections -MD -MF &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  bazel-out/k8-opt-exec-34F00540/bin/external/zlib/_objs/zlib/infback.d &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  -frandom-seed&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;bazel-out/k8-opt-exec-34F00540/bin/external/zlib/_objs/zlib/infback.o &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  -iquote external/zlib -iquote bazel-out/k8-opt-exec-34F00540/bin/external/zlib &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  -isystem external/zlib/zlib/include &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  -isystem bazel-out/k8-opt-exec-34F00540/bin/external/zlib/zlib/include -g0 &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  -Wno-unused-variable -Wno-implicit-function-declaration -fno-canonical-system-headers &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  -Wno-builtin-macro-redefined -D__DATE__&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;redacted&amp;#34;&lt;/span&gt; -D__TIMESTAMP__&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;redacted&amp;#34;&lt;/span&gt; &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  -D__TIME__&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;redacted&amp;#34;&lt;/span&gt; -c external/zlib/infback.c -o &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  bazel-out/k8-opt-exec-34F00540/bin/external/zlib/_objs/zlib/infback.o
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;这是另一个：&lt;/p&gt;</description>
    </item>
  </channel>
</rss>
