本地缓存 vs 远程缓存:优缺点及使用场景
做 Android 构建优化的朋友,迟早都会面对一个问题:到底该用本地缓存还是远程缓存?
我以前也纠结过。有一回项目从几十个模块膨胀到一百多,本地缓存经常撑爆磁盘,团队里大家各自跑构建,缓存完全没法共享。后来引入远程缓存,结果又遇到网络抖动导致构建变慢。折腾一圈下来,我才真正摸清这两兄弟的脾气。
今天我就把它们的优缺点和使用场景掰开揉碎了讲。你想想看,搞懂了这些,以后选方案就不会再“拍脑袋”了。
本地缓存:快,但孤独
本地缓存就是把构建产物(比如 class 文件、dex、资源包)存在你电脑的 ~/.gradle/caches 里。AGP 默认就开着。
它的优点很直接:快。没有网络开销,每次读缓存就是磁盘 I/O,SSD 上基本毫秒级响应。我记得有个老兵项目,第一次全量编译要 10 分钟,启用本地缓存后,如果只改了一行 Java,增量编译 20 秒就搞定。
但它也有明显的短板——跨机器不共享。你想想看,团队里 10 个人,每个人都在本地生成一份同样的缓存,浪费磁盘不说,新同学拉完代码第一次构建还得从头编译。另一个问题是磁盘占用,我见过有人 .gradle 目录膨胀到 50GB,直接撑爆 C 盘。
适用场景:
- 个人开发机,每次只改少量代码
- 网络不稳定或离线办公环境
- 小项目(几十个模块以内)
远程缓存:共享,但有代价
远程缓存把构建产物上传到远端存储(比如 HTTP 服务器、S3、Nexus 等),其他机器可以下载复用。常用方案是 build-cache-http 或者自定义存储后端。
它最大的价值是团队共享。举个例子:CI 机器上午全量构建过一次,下午开发者拉代码后只需要下载缓存,增量编译时间从 8 分钟降到 1 分钟。我在项目中多次见到,远程缓存让团队整体的构建命中率从 20% 提升到 70% 以上。
但远程缓存也有坑:
- 网络延迟:上传和下载都要走网络,如果带宽不够或者服务器在国外,反而比本地编译还慢。
- 存储成本:需要运维维护后端,清理过期缓存也是麻烦事。
- 缓存失效风险:如果 AGP 升级或者构建脚本变动,所有远程缓存可能全部失效,这个过程很痛苦。
我做过一个实验:50MB 的构建产物,局域网远程缓存下载耗时约 3 秒;但如果网络抖动,重试两三次就十几秒过去了。所以千万别盲目上远程缓存。
避坑指南:
我曾经遇到过一个事故:团队把远程缓存直接接到对象存储上,结果某个模块输出包含了路径,导致不同机器的缓存互相覆盖,构建时随机报错。排查了两天才找到原因。记住:远程缓存必须保证产物 key 与平台无关,使用相对路径或者哈希生成 key。
核心对比一览
| 维度 | 本地缓存 | 远程缓存 |
|---|---|---|
| 读写速度 | 极快(磁盘 I/O) | 受网络延迟影响 |
| 共享能力 | 仅本机 | 全团队/CI |
| 磁盘占用 | 每台机器独立占用 | 服务端统一存储 |
| 运维成本 | 零 | 需部署和清理策略 |
| 缓存命中率 | 高(但只对本机先前的构建) | 高(团队共享,但受版本影响) |
| 适用项目规模 | 小到中型 | 中到大型团队 |
使用场景归纳
实际项目中,我通常按以下几类情况来决策:
- 个人日常开发:肯定优先本地缓存。你想想,改几行代码就要上传下载,何必呢。
- CI/CD 持续集成:必须上远程缓存。每次构建都是全新环境,没有远程共享的话,CI 中的增量编译就是个笑话。我个人习惯把远程缓存和 CI 构建任务深度绑定,比如只在 release 分支全量构建后产生缓存,其他分支直接复用。
- 大型团队多人协作:建议本地缓存 + 远程缓存同时开启。AGP 默认会先查本地,如果 hit 则直接使用,miss 了再查远程。这个组合最实用。
- 网络受限环境:只能本地缓存。你可以考虑在公司内网搭建远程缓存服务器,降低延迟。
我的一个技巧:
在 gradle.properties 中可以通过 org.gradle.caching=true 开启缓存。如果你想同时用两种缓存,需要配置 buildCache 块:
// settings.gradle.kts
buildCache {
local {
isEnabled = true
directory = File(rootDir, ".build-cache")
// 设置最大大小
removeUnusedEntriesAfterDays = 7
}
remote(HttpBuildCache::class) {
url = uri("http://your-cache-server/cache/")
isPush = true
// 设置该远程缓存只存储关键构建产物
}
}
最后说两句
本地缓存和远程缓存不是二选一的关系,更像是“搭档”。我的经验是:小项目只开本地,大项目一定混用。但别忘了定期清理缓存,特别是本地缓存,我见过有人积累了 2 年前的缓存,重建后速度反而变慢。嗯,今天就聊这么多,你先消化这些,下次我们聊聊如何监控缓存命中率,那可是优化效果的“照妖镜”。