如何使用 sccache?
解读
在国内 Rust 岗位面试中,**“如何加速编译”**是高频考点。sccache 作为 Mozilla 开源的分布式编译缓存工具,能把 rustc 产物缓存到本地磁盘或 Redis,二次编译时直接命中,CI 时间从十几分钟降到几十秒,是工程化落地的标配。面试官想确认:
- 你是否知道 Cargo 原生不支持跨项目共享增量;
- 能否在 公司内网 GitLab CI + 自建 Redis 场景下,把 sccache 配成“开箱即用、可灰度、可观测”的状态;
- 是否理解 缓存 key 的哈希因子(rustc 版本、代码、flags),避免“缓存污染”导致线上事故。
知识点
- sccache 与 ccache 差异:前者支持 Rust、C/C++、NVCC,后者仅 C 家族。
- 两种启动方式:
- 包管理器安装后
export RUSTC_WRAPPER=sccache; - 源码编译开启 S3、Redis、阿里云 OSS feature,满足国内云原生场景。
- 包管理器安装后
- 缓存 key 组成:rustc 版本、目标三元组、编译选项、源文件内容哈希,任何 –C opt-level 变动都会失效。
- 分布式安全:–SCCACHE_REDIS_KEY 做命名空间隔离,防止测试环境把生产缓存冲掉。
- 观测指标:
sccache –show-stats中 “cache hits” 与 “cache misses” 直接反映 ROI;Prometheus exporter 可对接夜莺监控。 - 常见坑:
– 路径中含中文空格导致命中率为 0;
– 忘记把 target 目录加入 .gitignore,CI 缓存 tar 包爆炸;
– Windows 上未关杀毒实时扫描,mmap 失败回退到慢速文件 IO。
答案
-
安装:
Ubuntu 源版本滞后,推荐用官方预编译静态 musl 包;
wget https://github.com/mozilla/sccache/releases/download/v0.7.4/sccache-v0.7.4-x86_64-unknown-linux-musl.tar.gz
解压后把单文件放到/usr/local/bin并chmod +x。 -
配置 Redis 后端(公司内网已搭 6.2 集群):
export SCCACHE_REDIS=redis://:yourPassword@10.0.0.55:6379/1 export SCCACHE_REDIS_KEY_PREFIX=rust-ci export SCCACHE_CACHE_SIZE=20G20G 可缓存 500 万行 Rust 项目两周迭代量,经验值。
-
让 Cargo 调用:
export RUSTC_WRAPPER=sccache export CARGO_INCREMENTAL=0 # 强制关增量,避免与 sccache 冲突 cargo build –release首次编译 8 min,第二次 45 s,命中率 96%。
-
CI 集成(GitLab Runner):
.gitlab-ci.yml里把SCCACHE_DIR: $CI_PROJECT_DIR/sccache缓存到key: rustc-$RUSTC_VERSION;
Job 结束执行sccache –stop-server把日志刷到 stdout,方便排查“非确定性编译”导致的 miss。 -
灰度与回滚:
若发现缓存污染,立即改 SCCACHE_REDIS_KEY_PREFIX 版本号,老 key 设 TTL 为 1 h,实现零停机回滚。
拓展思考
- 与 bazel-remote-cache 对比:Bazel 缓存粒度是“action”,Rust 规则尚不成熟;sccache 无需改造构建系统,在 Cargo 体系下 ROI 更高。
- Rust 1.78 的 –share-generics 与 sccache 叠加:目前仍互斥,等待 rustc 稳定化“模块化代码生成”后,可把泛型实例也缓存,命中率再提 10%。
- 安全合规:国内金融项目要求“源代码不出内网”,可编译 sccache 时关闭所有 upstream 特性,仅留本地磁盘后端,并用 国密 SM4 全盘加密 防止落地泄露。