GitLab CI 缓存完全指南:加速构建的终极实践

发布时间:2026/7/5 4:32:29
GitLab CI 缓存完全指南:加速构建的终极实践 GitLab CI 缓存完全指南加速构建的终极实践一、缓存的核心价值与工作原理1.1 什么是缓存1.2 缓存 vs 制品本质区别二、缓存配置基础语法2.1 cache 关键字基本结构2.2 缓存键key策略2.3 缓存策略policy三、多语言缓存实践3.1 JavaScript/Node.js 缓存3.2 Python 缓存3.3 Ruby 缓存3.4 Go 缓存四、高级缓存策略4.1 多缓存与回退键4.2 全局回退键4.3 禁用缓存或按作业覆盖4.4 分布式缓存五、完整实践示例六、总结The Begin点点关注收藏不迷路⬇ ⬇ 底部 ⬇ ⬇⚡ 在 CI/CD 流程中每次构建都重新下载依赖项是效率最低的行为之一。GitLab CI 的缓存机制通过复用之前下载的内容能显著缩短流水线执行时间。本文将全面解析缓存的工作原理、配置方法及多语言实践方案。一、缓存的核心价值与工作原理1.1 什么是缓存在 GitLab CI 中缓存是作业下载并保存的一个或多个文件。使用相同缓存的后续作业无需再次下载这些文件因此运行速度更快 。核心原则缓存是为了加速你的作业但它可能不存在所以不要依赖它来传递必要的构建结果 。缓存是一个优化手段而非必需的数据传递机制。1.2 缓存 vs 制品本质区别理解缓存和制品的区别是正确使用两者的前提对比维度 缓存Cache 制品Artifacts用途存储从互联网下载的依赖项在阶段间传递中间构建结果存储位置Runner 本地或分布式缓存S3GitLab 服务器跨流水线✅ 后续流水线可复用❌ 同一流水线结束后通常过期生命周期长期存在按 key 复用默认 30 天过期依赖关系可选不存在时重新下载即可必需后续阶段依赖其结果一句话总结缓存是为了加快速度但可以不存在制品是为了传递结果所以必须存在。流水线 #2流水线 #1生成下载并保存下载命中跨流水线复用同一流水线传递Job A制品存储于GitLab缓存存储于RunnerJob B制品后续阶段使用缓存加速构建二、缓存配置基础语法2.1 cache 关键字基本结构在.gitlab-ci.yml中使用cache关键字定义缓存job:cache:key:$CI_COMMIT_REF_SLUG# 缓存的唯一标识paths:# 需要缓存的目录或文件-vendor/-node_modules/policy:pull-push# 缓存策略拉取/推送核心字段说明字段作用示例key缓存的唯一标识决定不同作业/分支是否共享缓存$CI_COMMIT_REF_SLUGpaths需要缓存的文件或目录路径相对于项目根目录- node_modules/policy缓存策略pull只拉取、push只推送、pull-push默认policy: pull2.2 缓存键key策略缓存键是决定缓存能否被复用的核心。不同的 key 会生成不同的缓存互不影响。按分支隔离推荐cache:key:$CI_COMMIT_REF_SLUG# 每个分支独立缓存paths:-node_modules/此配置可防止不同分支意外覆盖缓存 。按作业和分支隔离cache:key:$CI_JOB_NAME-$CI_COMMIT_REF_SLUG# 每个作业分支独立缓存paths:-vendor/按依赖文件计算键精准失效cache:key:files:# 根据文件内容生成哈希作为缓存键-package-lock.jsonpaths:-node_modules/当package-lock.json变化时缓存自动失效确保依赖变更时重新下载 。分支间共享缓存谨慎使用cache:key:global-cache# 所有分支共享同一个缓存paths:-shared/2.3 缓存策略policypolicy控制作业如何与缓存交互策略行为适用场景pull-push默认拉取已有缓存执行后推送更新大多数场景pull只拉取不推送只读作业如测试避免不必要的缓存写入push不拉取执行后推送负责生成缓存的专用作业实用示例条件化缓存策略根据分支动态调整策略减少默认分支的缓存写入开销 conditional-policy:rules:-if:$CI_COMMIT_BRANCH $CI_DEFAULT_BRANCHvariables:POLICY:pull-push-if:$CI_COMMIT_BRANCH!$CI_DEFAULT_BRANCHvariables:POLICY:pullcache:key:gemspolicy:$POLICYpaths:-vendor/bundlescript:-echo 缓存策略根据分支动态变化三、多语言缓存实践3.1 JavaScript/Node.js 缓存npm 项目将 npm 缓存目录放在项目内按分支缓存 default:image:node:latestcache:key:$CI_COMMIT_REF_SLUGpaths:-.npm/before_script:-npm ci--cache .npm--prefer-offline# 使用缓存离线安装基于锁文件计算键推荐cache:key:files:-package-lock.jsonpaths:-node_modules/Yarn 项目使用yarn-offline-mirror缓存压缩包 cache:key:files:-yarn.lockpaths:-.yarn-cache/3.2 Python 缓存pip 项目设置PIP_CACHE_DIR到项目内目录 variables:PIP_CACHE_DIR:$CI_PROJECT_DIR/.cache/pipcache:key:files:-requirements.txtpaths:-.cache/pip-venv/3.3 Ruby 缓存Bundler 项目将 gem 安装到项目内目录并缓存 cache:key:files:-Gemfile.lockprefix:$CI_JOB_NAME# 不同作业使用不同缓存前缀paths:-vendor/rubybefore_script:-bundle config set--local path vendor/ruby-bundle install-j $(nproc)3.4 Go 缓存Go Modules设置GOPATH到项目内目录 variables:GOPATH:$CI_PROJECT_DIR/.gocache:paths:-.go/pkg/mod/# 缓存 Go 模块四、高级缓存策略4.1 多缓存与回退键使用多个缓存每个作业最多4个test-job:cache:-key:files:-Gemfile.lockpaths:-vendor/ruby-key:files:-yarn.lockpaths:-.yarn-cache/回退缓存键当找不到指定缓存时尝试使用回退缓存 test-job:cache:-key:cache-$CI_COMMIT_REF_SLUGfallback_keys:-cache-$CI_DEFAULT_BRANCH# 主分支缓存作为回退-cache-default# 最终回退paths:-vendor/ruby这确保了新分支能复用主分支的缓存加速首次构建。4.2 全局回退键使用CACHE_FALLBACK_KEY变量指定全局回退缓存 variables:CACHE_FALLBACK_KEY:global-fallbackjob:cache:key:$CI_COMMIT_REF_SLUGpaths:-binaries/4.3 禁用缓存或按作业覆盖完全禁用缓存job:cache:[]# 空列表表示该作业不使用缓存继承全局配置并覆盖特定设置使用 YAML 锚点default:cache:global_cachekey:$CI_COMMIT_REF_SLUGpaths:-node_modules/policy:pull-pushjob:cache::*global_cache# 继承所有设置policy:pull# 仅覆盖 policy4.4 分布式缓存如果使用多个 Runner需要启用分布式缓存以确保在不同 Runner 间共享缓存 在config.toml中配置 S3 作为共享缓存后端[[runners]] [runners.cache] Type s3 Path bucket/path/prefix Shared true [runners.cache.s3] BucketName foobar AccessKey changeme SecretKey changemeGitLab.com 的共享 Runner 即采用分布式缓存方式 。五、完整实践示例以下是一个综合配置示例结合了多语言缓存和最佳实践stages:-deps-test-builddefault:image:node:latestvariables:PIP_CACHE_DIR:$CI_PROJECT_DIR/.cache/pipGOPATH:$CI_PROJECT_DIR/.go# 安装依赖的专用作业推送缓存install deps:stage:depsscript:-npm install jest-junitcache:-key:$CI_COMMIT_REF_SLUGpaths:-node_modules/-key:files:-requirements.txtpaths:-.cache/pippolicy:push# 测试作业只拉取缓存test:stage:testbefore_script:-npm install-g jestscript:-jest binarysearch.test.jscache:key:$CI_COMMIT_REF_SLUGpaths:-node_modules/policy:pull# Python 测试独立缓存python-test:stage:testimage:python:latestcache:key:files:-requirements.txtpaths:-.cache/pipbefore_script:-pip install-r requirements.txt--cache-dir .cache/pipscript:-pytest .六、总结实践要点说明缓存定位缓存是为了加速构建不是必需的传递机制键设计使用$CI_COMMIT_REF_SLUG按分支隔离或用files基于依赖文件生成键多缓存每个作业最多4个缓存可分别缓存不同依赖策略选择用pull策略避免不必要的缓存写入分布式多 Runner 环境下启用 S3 分布式缓存回退键通过fallback_keys让新分支复用主分支缓存核心启示GitLab CI 缓存的本质是用空间换时间——通过复用依赖文件换取更快的构建速度。合理的缓存键设计是成功的关键过于宽泛会导致缓存污染过于精细则命中率低。推荐使用files结合锁文件的方式在依赖变更时自动失效在依赖不变时稳定命中。The End点点关注收藏不迷路⬆ ⬆ 顶部 ⬆ ⬆