本地缓存目录配置:默认位置、自定义路径、多项目共享、清理策略
构建缓存的物理存储位置直接决定了磁盘占用、多项目复用能力以及运维成本。Gradle 为本地缓存目录提供了从零配置到精细化管理的完整链路,本章将逐一拆解其默认机制、自定义配置方法、多项目共享方案与清理策略。
3.1 默认缓存目录层级与位置
Gradle 构建缓存(Build Cache)的本地存储与依赖缓存(Dependency Cache)、守护进程(Daemon)等共享 Gradle User Home 目录。在不做任何配置时,缓存存放于:
| 操作系统 | 默认路径 |
|---|---|
| Linux / macOS | |
| Windows | |
目录名中的 build-cache-1 中的数字 1 代表缓存存储格式版本。Gradle 升级后若格式产生不兼容变更,会自动创建 build-cache-2 等新目录,旧版本保留供回滚使用。
# 查看当前 Gradle 用户目录位置
gradle --version | grep "Gradle user home"
# 查看缓存目录大小(Linux/macOS)
du -sh ~/.gradle/caches/build-cache-*
3.2 缓存目录内部结构
进入 build-cache-1 后,缓存条目以哈希值命名的子目录存放,结构如下:
build-cache-1/
├── 3a/
│ └── 3a4f8c2d...ab12
│ ├── output.bin # 构建产物序列化文件
│ └── metadata.json # 包含缓存键、任务类型、时间戳
├── b9/
│ └── b9e0a7f1...cd34/
│ ├── output.bin
│ └── metadata.json
└── gc.properties # 垃圾回收状态文件
- 两级哈希目录:前缀目录(如
3a/)避免单个目录下文件过多。 - output.bin:序列化的任务输出产物。
- metadata.json:记录缓存条目的来源、创建时间、Gradle 版本等元信息。
- gc.properties:记录最近一次的垃圾回收 (GC) 时间戳,用于指导清理策略。
3.3 自定义缓存路径
当默认路径所在磁盘空间不足,或需要将缓存挂载到高速 SSD、内存盘时,可通过以下三种方式自定义:
3.3.1 通过 gradle.properties 全局配置
在 ~/.gradle/gradle.properties 中设置:
org.gradle.cache.tasks=true
org.gradle.cache.local=/data/build-cache
该设置对当前用户的所有 Gradle 项目生效。注意,此属性仅控制 构建缓存 位置,并不影响依赖缓存路径。
3.3.2 通过系统属性或环境变量
在构建命令中临时指定:
# 系统属性方式
./gradlew build -Dorg.gradle.cache.local=/tmp/gradle-cache
# 环境变量方式(覆盖优先级最高)
export GRADLE_CACHE_LOCAL=/fast-ssd/cache
./gradlew build
系统属性优先级高于 gradle.properties,环境变量又高于系统属性。具体优先级链为:
- 命令行
-D参数 - 环境变量
GRADLE_CACHE_LOCAL - 项目级
gradle.properties - 用户级
~/.gradle/gradle.properties - Gradle 默认值 (
~/.gradle/caches/build-cache-1)
3.3.3 在 settings.gradle 中编程指定
适用于需要根据不同 CI 环境动态切换路径的场景:
// settings.gradle.kts
buildCache {
local {
isEnabled = true
directory = File("/mnt/nvme/build-cache")
// 还可以同时配置 push/pull 策略
isPush = System.getenv("CI") == null // 本地构建 push,CI 仅 pull
}
}
Kotlin DSL 与 Groovy DSL 均可使用,推荐在 CI 场景下用此方式保证路径随环境变量变化。
Could not create local cache directory /custom/path/build-cache-1 ... (Permission denied)
3.4 多项目共享本地缓存
当多个独立项目在同一台机器上构建时,若它们使用了完全相同的依赖和任务配置,可以通过共享同一个本地缓存目录来加速构建。配置方式如下:
3.4.1 共享模式原理
- 所有项目设置
directory指向同一个路径。 - 缓存条目的键由任务类型、输入文件的哈希、输出文件名等决定——与项目名称无关。
- Git 分支切换或模块重组不会使共享缓存失效,只要输出内容相同即可命中。
3.4.2 实现共享配置
在每项目的 settings.gradle.kts 中统一指定:
// 项目 A 与项目 B 均配置
buildCache {
local {
directory = File("/team-shared-cache/gradle-build-cache")
isPush = true // 允许将当前项目的缓存写入共享目录
isPull = true // 允许从共享目录读取缓存
}
}
3.4.3 共享注意事项
| 场景 | 建议 |
|---|---|
| CI 多 Agent 同机 | 设置 isPush = true 仅在一个 Agent 上启用,避免写入冲突。实际用只读挂载更安全。 |
| 本地开发机共享 | 确保所有项目使用相同的 Gradle 版本,不同版本的缓存格式不兼容。 |
| 缓存磁盘配额 | 在共享目录上设置磁盘配额(Linux quota / Windows 磁盘配额),防止缓存膨胀占满系统盘。 |
| 并发写入 | Gradle 使用文件锁机制,但极端并发时可能导致部分丢失。建议共享目录仅用于 读取,写入分散到各自临时目录。 |
GRADLE_CACHE_LOCAL 环境变量注入路径,避免修改项目配置文件。3.5 清理策略与实战
Gradle 本身不提供自动定时清理本地缓存的机制,需要开发者根据使用情况实施清理。以下是三种常用策略:
3.5.1 Gradle 自带的 GC(Garbage Collection)
Gradle 会在构建结束时检查 gc.properties 中的时间戳,若距离上次 GC 超过 24 小时,会触发一次 弱引用清理——只删除那些不再被任何 Gradle 守护进程引用的缓存文件。此方式不会检查缓存时效或大小。
3.5.2 手动定期清理
通过 cron 任务或 CI 构建前的脚本,按时间或大小阈值清理:
#!/bin/bash
# 清理 7 天前未被访问的缓存条目
CACHE_DIR=~/.gradle/caches/build-cache-1
find "$CACHE_DIR" -type d -name "??" -exec sh -c '
for dir in "$1"/*; do
if [ -f "$dir"/output.bin ]; then
last_access=$(stat -c %X "$dir"/output.bin)
now=$(date +%s)
# 7 天 = 604800 秒
if [ $((now - last_access)) -gt 604800 ]; then
rm -rf "$dir"
fi
fi
done
' _ {} \;
3.5.3 使用 Gradle Enterprise 或第三方插件
若使用 Gradle Enterprise,可通过其缓存管理界面配置 TTL(Time To Live)和大小上限。社区插件如 gradle-cache-cleanup 也提供了按大小、按时间、按匹配模式清除的能力:
// build.gradle.kts
plugins {
id("com.github.ben-manes.gradle-versions") version "0.51.0"
}
tasks.register("cleanBuildCache") {
doLast {
project.gradle.getGradleUserHomeDir()
.resolve("caches/build-cache-1")
.listFiles()?.forEach { prefixDir ->
prefixDir.listFiles()?.forEach { cacheEntry ->
if (cacheEntry.isDirectory) {
// 保留最近 3 天内的
if (System.currentTimeMillis() - cacheEntry.lastModified() > 3 * 86400_000L) {
cacheEntry.deleteRecursively()
}
}
}
}
}
}
build-cache-1 目录是安全的,Gradle 会在下次构建时自动重建。但更推荐按访问时间删除单个条目,避免清空后首次构建无缓存命中。3.6 性能优化:缓存目录与存储介质
- SSD 优先:将缓存目录放在 NVMe SSD 或 RAM Disk 上,可减少 30%~50% 的缓存写入/读取延迟。
- 避免跨网络文件系统:NFS/SMB 等网络挂载会增加 I/O 延迟,仅适用于只读共享场景。读写时建议用本地盘。
- 目录大小监控:在生产环境设置监控,当
build-cache-1目录超过 10GB 时发送告警。 - 与 CI 工作目录隔离:CI 中应显式指定缓存路径,不要放在项目 checkout 目录内,防止清理 workspace 时误删缓存。
3.7 本章小结
本地缓存目录是 Gradle 构建缓存能力的基石。通过理解默认路径结构、灵活运用三种自定义方式、合理规划多项目共享方案以及实施有效的清理策略,可以在享受构建加速的同时,避免磁盘空间失控。实际生产环境中,建议将目录配置与 CI/CD 系统变量绑定,并通过定期清理脚本保持缓存处于健康状态。