logo
0
0
Login
docs: 教程文档

利用缓存提升构建速度

介绍

众所周知,缓存是性能优化一个重要手段。在 CI 领域,利用好缓存能极大提升流水线构建速度!

下面以前端 NodeJS 为例,介绍两种有效的利用缓存提升构建速度的方法。

no cache

我们先准备一份 package.json ,里面有这些模块:

{ "dependencies": { "angular": "^1.8.3", "eslint": "^9.15.0", "jest": "^29.7.0", "koa": "^2.15.3", "next": "^15.0.3", "nuxt": "^3.14.159", "react": "^18.3.1", "vue": "^3.5.13", "webpack": "^5.96.1" } }

在流水线上执行 npm install,流水线配置文件:

main: push: "no-cache": docker: image: node:22-alpine stages: - name: npm install script: npm install

执行效果:

no-cache

由于没有 cache,会从网络下载资源,耗时约 23s。

volume cache

云原生构建 利用 Docker 的 volumes 功能,可在配置文件中通过声明 pipeline.docker.volumes, 将构建机上目录 mount 到容器中。构建任务可将下载好的依赖放入构建机缓存,供后续流水线使用。

Node 流水线配置文件:

main: push: "volume-cache": docker: image: node:22-alpine volumes: - node_modules:copy-on-write stages: - name: npm install script: npm install

多执行几次,命中缓存后执行效果:

fit volume cache

可以看到前面截图中 added 1973 packages from 1072 contributors 字样消失了,增加了 up to date 字样,无需从网络下载资源,耗时降为 13s。

volumes 的缺点是,缓存只在当前构建机有效。云原生构建 会根据项目构建并发情况,动态在几台构建机上分配一台作为当前流水线构建机,后续流水线分配了其他无缓存的构建机,仍会重新从网络下载资源。

Maven 流水线配置文件:

main: push: - docker: # 可以去 dockerhub 上 https://hub.docker.com/_/maven 找到您需要 maven 和 jdk 版本 image: maven:3.8.6-openjdk-8 volumes: - /root/.m2:cow stages: - name: build script: mvn clean package

Gradle 流水线配置文件:

master: push: - docker: # 可以去 dockerhub 上 https://hub.docker.com/_/gradle 找到您需要 gradle 和 jdk 版本 image: gradle:6.8-jdk8 volumes: - /root/.gradle:copy-on-write stages: - name: build script: ./gradlew bootJar

docker cache

云原生构建 还提供了一种 cache 方式:在一个镜像中 npm install 好依赖,然后缓存这个镜像在当前构建机,并推送到远端镜像源。

后续流水线使用时,若构建机有镜像缓存,则直接使用。若构建机无镜像缓存,则会从远端镜像源拉取下来。

docker:cache 内置任务使用示例:

master: push: - stages: - name: build cache image type: docker:cache options: dockerfile: cache.dockerfile by: - package.json - package-lock.json versionBy: - package-lock.json exports: name: DOCKER_CACHE_IMAGE_NAME - name: use cache image: $DOCKER_CACHE_IMAGE_NAME commands: - cp -r "$NODE_PATH" ./node_modules

cache.dockerfile 示例:

# 选择一个 Base 镜像 FROM node:16 # 设置工作目录 WORKDIR /space # 将 by 中的文件列表 COPY 过来 COPY . . # 根据 COPY 过来的文件进行依赖的安装 RUN npm ci # 设置好需要的环境变量 ENV NODE_PATH=/space/node_modules

无镜像,需要构建并推送镜像的效果:

build cache

可以看到耗时同直接 npm install 接近,约 31.5s。

后续构建,构建机无镜像,需要 pull 的效果,待补充

后续构建,若构建机有镜像,直接使用的效果:

local cache

耗时降到 2.7s,效果非常明显!

对比

缓存

  • volumes:缓存在构建机,效果好
  • docker:cache:缓存在构建机和远端,效果好

复杂度

  • volumes:配置简单,清晰易懂
  • docker:cache:配置复杂,涉及配置文件、dockerfile,有一定理解、使用成本

跨流水线

  • volumes:同一个构建机中,可跨流水线共享缓存,不可跨构建机
  • docker:cache:流水线执行过程中,流水线独享。缓存镜像构建完成、推送到远端后,可跨流水线、跨构建机使用

缓存更新

  • volumes:可控制读写权限,适用更多场景
  • docker:cache:重新构建缓存镜像并推送到远端,其他构建机需重新拉取。

完整示例

参见 .cnb.yml

具体效果对比,可于本仓库的云原生构建列表页查看流水线,或 fork 后自行尝试。