0

在 CI 上缓存的常用方法是将文件存储到存档,然后将其推送到某个存储,稍后下载并解压缩。很简单。

考虑来自https://github.com/actions/cache的示例

- name: Cache multiple paths
  uses: actions/cache@v2
  with:
    path: |
      ~/cache
      !~/cache/exclude
    key: ${{ runner.os }}-${{ hashFiles('**/lockfiles') }}

这个片段声明了什么?它说:“请尝试恢复我的缓存,不包括其中一些给出类似名称的缓存ubuntu-abfacada123456,然后执行其他操作,并以相同的名称返回作业存储缓存的末尾”。
我们也能够提供

    restore-keys: ${{ runner.os }}-*

当找不到完全匹配时,获取与模式对应的最新可用缓存key

由于其简单明了,这是最广泛的缓存方法之一。


介绍一下我的问题。我有一个有很多依赖项的大型 C++ 项目。它是分几个阶段构建的,还有很多事情需要做得更快。
简而言之,构建包括:

  • 准备docker镜像
  • 构建由 vcpkg 管理的依赖项
  • 使用 ccache 使用 cmake 构建项目
  • 运行测试

有3个点可以缓存

  • 泊坞窗图像层;大约 1.4Gb,?? 拉链
  • vcpkg 下载、构建数据、安装 build-root;约 5Gb,1.4Gb 压缩
  • 项目的ccache;高达 8Gb,2Gb 压缩

我已经尝试在 GitLab CI 和 GitHub Actions 上使用常规和常用的缓存技术。对于如此大量的数据,它们的效率不够高。默认缓存存储经常溢出并且较旧但仍然实际的档案被删除。

CI 假设多个 pull/merge 请求、提交、分支的多个构建;计划运行和手动运行。因此总缓存大小超过了通常的报价。

问题

  1. 存储几乎相同的文件需要太多的存储空间。构建与构建之间的差异小于缓存大小的 5%,通常高达 1%
  2. 归档 5Gb 的构建数据然后将其从构建机器上传到远程持久存储需要太多时间
  3. 带有缓存存档的存储比数据过时更频繁
  4. 一个全新的初始化干净构建机器仍然需要下载完整的缓存,但下载和解包时间总是比存档和上传少得多。

例如,我的 5Gb vcpkg build_dir 在 1 分钟 40 秒内下载和上传,但存档和上传需要 4 分钟 45 秒。我们很少更改vcpkg,通常没有更改上传。

所以任务是减少网络上的流量

解决方法

我想使用一些备份/恢复实用程序,例如rclonerestic存储差异数据。

工作流程几乎相同:

  • 下载缓存;
  • 做事,即构建/重建,假设这一步也自动检测要重建的内容;
  • 上传更新的缓存,只有区别
  • 使用标签标记上传的快照以供将来使用:日期、分支名称、内部版本号等。

关键问题是检测要下载哪个快照。
让我们考虑下一个用例。给定一个从 branch-A 到 branch-main 的 PR。Branch-A 仍在建设中,开发人员经常推动。PR 的每个下一个版本都应该使用前一个版本的缓存。PR 的第一次构建是指基础分支的缓存。

这是问题

有没有现成的问题解决方案?

您如何优化大型构建?

4

0 回答 0