受到 Xuanwo 的博客 的鼓动,我决定给自己的 Rust 项目 fireSeqSearch 加上 Sccache

sccache 概述

Sccache 可以简单看成 ccache 的 Rust 版。它有很多激动人心的特性,但那不在本文的范畴里。我在本地编译原有的项目时,只需运行 RUSTC_WRAPPER="sccache" cargo build 即可启用 sccache。默认的缓存路径为 ~/.cache/sccache

缓存 Cargo Registry

我原先的代码里 缓存了 ~/.cargo/registry,但这只是编译前的 crate.io registry, 而不是编译产生的目标代码,加速 CI 效果有限。

2022 年的笨办法

最开始,我仅仅是将 ~/.cache/sccache 添加到了缓存路径里。代码如下

      - name: Cache cargo registry and sccache
        uses: actions/cache@v3
        continue-on-error: false
        with:
          path: |
            ~/.cargo/registry
            ~/.cache/sccache

我的这个改动 误解了 sccache-action 的用法,并没有发挥它真正的强大之处。使用笨办法,大概 600M 的 ~/.cache/sccache 都会被 GitHub Action 缓存。随着时间推移,缓存文件的体积会膨胀,在 restore/save 时浪费时间。我自己的经验,在 macOS instance 上,接收 150M 的缓存就用了 3 分钟 (当然,这也与服务器实际运行情况有关)。

2023 年的新办法

感谢 Xuanwo 本人的答疑,我将 ~/.cache/sccache 移出了 actions/cache@v3改动后的代码如下

env:
  CARGO_TERM_COLOR: always
  RUSTC_WRAPPER: "sccache"
  SCCACHE_GHA_ENABLED: "true"
--- snip ---
      - name: Run sccache-cache
        uses: Xuanwo/sccache-action@c94e27bef21ab3fb4a5152c8a878c53262b4abb0
        with:
          version: "v0.4.0-pre.6"
      - name: Cache cargo registry
        uses: actions/cache@v3
        with:
          path: |
            ~/.cargo/registry

最直接的优点:细粒度缓存

相比旧办法,使用 sccache-action 并不会将 ~/.cache/sccache 作为整体上传到 GitHub Action Cache 里,而是会细粒度地将每个对象上传。

https://github.com/Endle/fireSeqSearch/actions/caches 里可以看到,大小从几K到几百K,乃至20M的对象被存入了 GHA。这很好地避免了旧方法中缓存文件夹膨胀的问题。

Screenshot of Github Action Cache

后记

在撰写完本文大概两周后,发现 xxchan 写了一篇博文 我如何动动小手就让 CI 时间减少了 10 分钟 比本文更详细、更完整。