为什么你该试试 Sccache?
Sccache 是由 mozilla 团队发起的类 ccache 项目,支持 C/CPP, Rust, nvcc 等语言,并将缓存存储在本地或者云存储后端。在 v0.3.3 版本中,Sccache 加入了原生的 Github Action Cache Service 支持;在后续的 v0.4.0-pre.6 版本中,社区对该功能进行了持续的改进,目前已经初步具备了在生产 CI 中应用的能力。
最近我在 PyO3/maturin 的 CI 中引入了 sccache 做了测试,发现它有如下优势:
- 部署配置更容易:无需指定
shared-key
,不需要操心 GHA 内部的 cache-from/cache-to 逻辑,配置SCCACHE_GHA_ENABLED: "true"
即可 - 支持多种语言:sccache 同时支持缓存 C/CPP,Rust,nvcc 多种语言的不同编译器,以 Rust 为例,配置
RUSTC_WRAPPER: "sccache"
即可 - 大部分场景下更快:sccache 缓存的是编译产物,不需要提前加载全部的缓存,也不需要在构建完成后上传缓存内容
- 并发任务友好:sccache 能在多个并发执行的 job/workflow 之间共享缓存,不需要等到构建结束
- 无缓存冲突:sccache 对每个编译产物的输入(参数,环境变量,文件等)进行 hash 计算,能构建一个全局的无冲突缓存,不会出现缓存冲突,不需要额外指定不同的 cache key
- 无供应商锁定:sccache 基于 opendal 构建,天然支持各种不同的存储服务,在未来的 CI 演进中,可以无缝切换到 s3/gcs/azlob 等服务中,不依赖 GHA Cache 服务
- 活跃维护中 (图穷匕见):sccache 目前由作者本人活跃贡献中,使用中遇到的问题可以直接提交反馈
以下是在 maturin 项目中的测试结果:
Cases | Sccache vs rust-cache (2nd) | Sccache vs rust-cache (3rd) |
---|---|---|
Test (ubuntu-latest, 3.7) | 59.72% | -1.68% |
Test (ubuntu-latest, 3.8) | -4.70% | -8.22% |
Test (ubuntu-latest, 3.9) | 30.72% | 10.81% |
Test (ubuntu-latest, 3.10) | 1.03% | 12.15% |
Test (ubuntu-latest, 3.11) | -10.16% | -29.35% |
Test (ubuntu-latest, pypy3.8) | 18.34% | -3.84% |
Test (ubuntu-latest, pypy3.9) | 5.13% | 22.90% |
Test (macos-latest, 3.7) | 11.87% | 5.65% |
Test (macos-latest, 3.8) | -7.82% | -13.65% |
Test (macos-latest, 3.9) | -17.98% | -45.20% |
Test (macos-latest, 3.10) | -13.20% | -15.38% |
Test (macos-latest, 3.11) | -17.44% | -29.55% |
Test (macos-latest, pypy3.8) | 14.83% | -23.32% |
Test (macos-latest, pypy3.9) | -28.03% | -38.56% |
Test (windows-latest, 3.7) | 30.08% | 24.22% |
Test (windows-latest, 3.8) | 35.11% | 41.14% |
Test (windows-latest, 3.9) | 9.24% | -5.28% |
Test (windows-latest, 3.10) | -8.56% | -15.81% |
Test (windows-latest, 3.11) | -1.39% | -36.49% |
Test (windows-latest, 3.8) | -19.99% | -35.54% |
Test (windows-latest, 3.9) | 18.95% | -8.55% |
表格中对比的是使用 sccache 第二次/第三次运行与使用 rust-cache 时候的差异,加粗的复数条目表示 sccache 比 rust-cache 更快。可以看到,随着 Cache 命中率的提高,sccache 对比 rust-cache 最大能取得将近 50% 的提升。
试试 Sccache 吧,任何不爽的地方请到 issues 反馈,同时欢迎参与贡献~
接下来的部分我会首先介绍 Github Action Cache Service 的内部 API 和它的工作原理,然后对比 rust-cache / sccache 实现的差异来说明为什么 sccache 更好/更快。
Github Action Cache Service 原理
Github Action Cache Service 本质上是一个支持 prefix query 的 immutable 存储服务,它提供了如下非公开的 API:
查询缓存
GET /cache?keys=abc,ab,a&version=v1
keys
: 指定一组逗号分割的查询 key,返回的结果是相同 version 下前缀匹配的最新 keyversion
:指定 cache key 所使用的 namespace
预留缓存
POST /caches
- inputs:
{key: <cache_key>, version: <cache_version>}
- outputs:
{cache_id: <cache_id>}
每一组 (key, version)
被预留之后,后续所有携带相同 key & version 的请求都会返回 already exists
错误,也就是说缓存无法覆盖。请求成功后会返回数字的 cache_id,后续上传缓存和创建缓存都会用到它。
上传缓存
PATCH /caches/[cache_id]
上传具体的缓存内容,使用 Content-Range
来标记本次上传的缓存位置。
创建缓存
POST /caches/[cache_id]
在所有的缓存内容都创建完毕后,可以使用这个 API 来创建缓存。只有在这个 API 响应成功后,缓存才能被查询到。
rust-cache 实现
在这套内部 API(合理怀疑是 Azure DevOps 服务提供的)的基础上,Github 提供了 actions/cache 供用户使用,而 rust-cache 正是基于 @actions/cache
实现的。
rust-cache 会基于 github job_id,rustc 版本,环境变量,Cargo.lock
等信息计算出一个 cache key,然后把 ~/.cargo
和 ./target
打包到一起上传。如果 cache 命中就加载到本地并解压缩使用,如果 cache miss,则会在 post action 中将 cache 上传。
rust-cache 的优势是整个过程只会调用一次 GHA Cache 的 API,很少会触发 rate limit,缺点是一旦 cache 没有命中,就需要完全从零构建。
sccache 实现
sccache 的 GHA 实现则是完全基于文件的:
sccache 会根据每一次 rustc 调用时传入的环境变量,二进制,编译参数,输入文件等信息计算一个 hash 作为 cache key,如果文件存在就直接从存储服务中加载,跳过本次编译操作,否则就进行编译并将结果写入到存储服务中。这就意味着:
- sccache 不需要处理不同输入带来的缓存冲突,可以使用总是唯一的 hash 作为 cache key
- sccache 可以在 rustc 编译时下载需要缓存,不需要提前加载全部的内容,也不需要在 Job 完成后全部上传
- sccache 缓存加载逻辑不强依赖于 Cargo.lock 本身,即使在依赖出现大量变化的情况下,也能够重用缓存
- sccache 可以在并发的 Job 之间重用缓存,因为大家共享同一个无冲突的存储空间
不仅如此,sccache 还能够应用于 c/cpp 等语言的编译缓存,如果项目中同时还存在 gcc/clang 等编译器的使用,只需要简单配置即可共享缓存。
为了帮助用户更好地在 Github Action 中使用 Sccache,我们开发了 sccache-action。不过我的 PR 目前还没有合并,可以先使用我的 fork:
- name: Sccache Setup # Just for test, come back to upstream after released uses: Xuanwo/sccache-action@c94e27bef21ab3fb4a5152c8a878c53262b4abb0 with: version: "v0.4.0-pre.6"
接下来只需要配置两个环境变量即可:
env: SCCACHE_GHA_ENABLED: "true" RUSTC_WRAPPER: "sccache"
在每个 Job 的末尾,sccache-action
会输出本次 Cache 的使用情况:
/opt/hostedtoolcache/sccache/0.4.0-pre.6/x64/sccache --show-stats Compile requests 1887 Compile requests executed 1035 Cache hits 836 Cache hits (C/C++) 22 Cache hits (Rust) 814 Cache misses 189 Cache misses (Rust) 189 Cache timeouts 0 Cache read errors 0 Forced recaches 0 Cache write errors 0 Compilation failures 10 Cache errors 0 Non-cacheable compilations 0 Non-cacheable calls 852 Non-compilation calls 0 Unsupported compiler calls 0 Average cache write 0.051 s Average compiler 1.132 s Average cache read hit 0.000 s Failed distributed compilations 0 Non-cacheable reasons: crate-type 521 - 320 unknown source language 11 Cache location ghac, name: sccache-v0.4.0-pre.6, prefix: /sccache/
用户可以根据这些信息来调整自己使用 sccache 的策略。
总结
Sccache 以一种全新的方式使用 GHA Cache 来对 Rust 项目进行编译加速,相比于现存的方案有如下优点:
- 部署配置更容易
- 支持多种语言
- 大部分场景下更快
- 并发任务友好
- 无缓存冲突
- 无供应商锁定
- 活跃维护中
欢迎大家在自己的项目中尝试和使用 Sccache!
作者:漩涡 @databend
关于 Databend
Databend 是一款开源、弹性、低成本,基于对象存储也可以做实时分析的新式数仓。期待您的关注,一起探索云原生数仓解决方案,打造新一代开源 Data Cloud。
Databend 文档:https://databend.rs/
Wechat:Databend

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
2023年 DevOps 七大趋势
随着时间的推移,很明显 DevOps 已经成为最高效的敏捷框架中的无人不知晓的名字。越来越多的企业(包括各类规模企业)正在采用 DevOps 方法来简化其运营效率。DevOps 的新时代趋势已经见证了其使用率的持续上升。 由于需求的变化和现代软件的复杂性,如今的公司需要各种各样的平台和操作系统,因此 DevOps 更多的是将企业推向更高的高度并利用技术帮助企业实现商业目标和价值。DevOps 中的最新技术趋势基于最佳实践,帮助推动企业在数字化进步驱动的现代经济中的绩效。一起来看看在未来一年,DevOps 的发展趋势是怎样的。 1. DevSecOps 随着安全成为数字时代最重要的问题之一,企业已经整合了 DevSecOps 生命周期,从而进一步强化安全,同时 DevSecOps 也被用于简化治理和提高可见性。DevSecOps 的主要思想是安全应该遵循的“左移”方法,而不是事后修复和弥补。根据最新的 DevSecOps 趋势,大约 40% 的企业有在使用 DAST 测试,50% 在使用 SAST,其余的企业通过扫描依赖项和容器来确保软件安全。 有一个非常典型“安全左移”例子与大家分享,...
- 下一篇
下一代编解码技术Ali266在视频超高清领域的应用展望
超高清与各领域的需求融合和创新正在发生。 2022年是一个体育大年,众多世界级体育赛事通过视频直播、转播等形式给观众带来畅爽的观看体验。 2022年北京冬奥会,实现了奥运会历史上首次赛事全程4K制作播出,并在开幕式上提供了8K超高清公共信号,让观众可以享受到超高清视频带来的更加清晰、真实和沉浸的比赛画面。 随着国家政策持续发力、市场需求不断增长,视频作为信息传播的重要载体,正在经历从标清、高清到4K超高清、8K超高清的发展。与此同时,超高清视频应用范围也渗透至各行各业,从广播电视、文化娱乐,到安防监控、医疗影像,超高清与各领域的需求融合和创新正在发生。 01 超高清产业风口vs编码效率困境 从标清到8K超高清,视频分辨率从(小于)1280720增加到(大于或等于)76804320,画面像素从30万像素增加到3200万像素以上。 除了高分辨率外,在高帧率、高色深、宽色域、高动态范围、三维立体声上各项指标都显著提升。帧率从24fps发展到60fps,再到120fps;位深从8bit发展到10bit,再到12bit;从SDR(标准动态范围)发展到HDR(高动态范围);从窄色域发展到宽色域。 ...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- Springboot2将连接池hikari替换为druid,体验最强大的数据库连接池
- CentOS8安装MyCat,轻松搞定数据库的读写分离、垂直分库、水平分库
- CentOS8编译安装MySQL8.0.19
- CentOS6,CentOS7官方镜像安装Oracle11G
- CentOS7,8上快速安装Gitea,搭建Git服务器
- SpringBoot2整合Thymeleaf,官方推荐html解决方案
- MySQL8.0.19开启GTID主从同步CentOS8
- SpringBoot2更换Tomcat为Jetty,小型站点的福音
- Red5直播服务器,属于Java语言的直播服务器
- CentOS6,7,8上安装Nginx,支持https2.0的开启