gitlab-ci/cd(六)cache机制

Cache 的使用方法

首先 cache 的定义范围可以全局定义,这样所有的 job 都会采用这个全局定义的 cache 设置。当然,每个 job 内也可以定义自己特有的 cache 来覆盖全局的配置。

Cache 在使用上主要的配置有以下几种:

1. Cache:paths

paths主要是来指定需要被缓存的文件路径,需要特别指出的是这里的 paths 是相对路径,是相对于gitlab中项目目录的路径,也就是说被缓存的文件都是在项目目录之内的。 如果在 job 内部也定义了 cache 配置,全局的配置就会被覆盖

例子:在仓库中创建cattest.txt。job1:赋值内容到文件,并覆盖全局配置

job2:因为job1覆盖全局,所以job的一个cat获取到job1的赋值

####.gitlab-ci.yml
stages:
   - test
   - test2
cache:
   paths:
     - cattest.txt

job1:
   stage: test
   script:
     - cat cattest.txt
     - echo "aaaaaaaaaa" > cattest.txt
     - cat cattest.txt
job2:
   stage: test2
   cache:
     paths:
       - cattest.txt
   script:
     - cat cattest.txt
     - echo "bbb" >> cattest.txt
     - cat cattest.txt
GitOps、新兴技术能力gitlab-ci/cd(六)cache机制插图
job1截图
GitOps、新兴技术能力gitlab-ci/cd(六)cache机制插图1
job2截图

2. Cache:key

由于 cache 是被不同的 job 所共享,如果不同的 jobs采用了不同的 path 配置,那么 cache 会在每个 job 被执行的时候被覆盖。cache:key 就是为了解决这个问题,当我们给不同 job 定义了不同的 cache:key 时, 每个 job 都会有一个独立的 cache,不同的 key 下的缓存也不会相互影响。

比如,不同的分支采用不同的 cache,防止分支之间相互影响:

cache:
  key: ${CI_COMMIT_REF_SLUG}

比如每个分支的每个 job 使用不同的 cache :

cache:
  key: "$CI_JOB_NAME-$CI_COMMIT_REF_SLUG"

再比如每个分支的每个 job 使用不同的 stage:

cache:
  key: "$CI_JOB_STAGE-$CI_COMMIT_REF_SLUG"

比如不同的分支之间需要共享 cache,但是 pipeline 中的 job 之间的 cache 是相互独立的:

cache:
  key: ${CI_JOB_NAME}

最后,当 key 没有被特别定义的时候,默认为 default,所有没定义 key 的 cache 使用的是同一份 cache,会随着 job 的执行一直被覆盖

思考:如果上述path例子添加了key,那么cat会是什么结果呢?

stages:
   - test
   - test2
cache:
   paths:
     - cattest.txt

job1:
   stage: test
   cache:
     paths:
       - cattest.txt
     key:
        key1
   script:
     - cat cattest.txt
     - echo "aaaaaaaaaa" > cattest.txt
     - cat cattest.txt
job2:
   stage: test2
   cache:
     paths:
       - cattest.txt
     key:
        key2
   script:
     - cat cattest.txt
     - echo "bbb" >> cattest.txt
     - cat cattest.txt
GitOps、新兴技术能力gitlab-ci/cd(六)cache机制插图2
job1
GitOps、新兴技术能力gitlab-ci/cd(六)cache机制插图3
job2

3. Cache:policy

在默认情况下,如果有 cache 的配置,那么每个 job 会在开始执行前将对应路径的文件下载下来,并在任务结束前重新上传,不管文件是否有变化都会如此操作。这个默认的配置是 cache:policy 中的 pull-push 策略。

但是如果我们已经知道,某个 job 只是使用的其他 job 改变的文件,自身并无改变对应路径的文件,那么就不需要进行文件上传操作,采用pull 策略即可。

反过来,某个 job 不依赖于其他 job 改变的文件,自身改变的文件被其他 job 所依赖,那么就不需要在 job 开始前进行文件下载操作,采用push 策略。这样减少了不必要的操作,在一定程度上节约了时间。

stages:
   - test
   - test2
   - test3
cache:
   paths:
     - cattest.txt

job1:
   stage: test
   cache:
     paths:
       - cattest.txt
     key:
       key-cache
     policy: pull
   script:
     - cat cattest.txt
     - echo "aaaaaaaaaa" > cattest.txt
     - cat cattest.txt
job2:
   stage: test2
   cache:
     paths:
       - cattest.txt
     key:
       key-cache
     policy: pull-push
   script:
     - cat cattest.txt
     - echo "bbb" >> cattest.txt
     - cat cattest.txt
job3:
   stage: test3
   cache:
     paths:
       - cattest.txt
     key:
       key-cache
     policy: pull-push
   script:
     - cat cattest.txt
GitOps、新兴技术能力gitlab-ci/cd(六)cache机制插图4
job1
GitOps、新兴技术能力gitlab-ci/cd(六)cache机制插图5
job2
GitOps、新兴技术能力gitlab-ci/cd(六)cache机制插图6
job3

注意:cache的Key缓存是整条流水线缓存。即定义了key1运行第一次pipeline,第二次运行时,会读取上一次的缓存【当然看是否启用了Cache:policy】,如果没有设置的key,默认值是default依然如此

stages:
   - test
   - test2
cache:
   paths:
     - cattest.txt
     - cattest2.txt

job1:
   stage: test
   cache:
     paths:
       - cattest.txt
     key:
       key-cache-new
    
   script:
     - cat cattest.txt
     - echo "aaaaaaaaaa" > cattest.txt
     - cat cattest.txt
job2:
   stage: test2
   cache:
     paths:
       - cattest2.txt
     
   script:
     - cat cattest2.txt
     - echo "bbb" >> cattest2.txt
     - cat cattest2.txt
GitOps、新兴技术能力gitlab-ci/cd(六)cache机制插图7
第一次job1
GitOps、新兴技术能力gitlab-ci/cd(六)cache机制插图8
第一次job2
GitOps、新兴技术能力gitlab-ci/cd(六)cache机制插图9
第二次的job1
GitOps、新兴技术能力gitlab-ci/cd(六)cache机制插图10
第二次的job2

4. Cache 的继承

如果在使用中,有 job 大部分配置跟全局配置是一样的,但是部分不同,就可以采用继承的方式,而不必全部重写。例如,仅需要覆盖 cache:policy的配置:

stages:
   - test
   - test2
   - test3
cache:
   paths:
     - cattest.txt

job1:
   stage: test
   cache:
     paths:
       - cattest.txt
     key:
       key-extend
     policy: pull
   script:
     - cat cattest.txt
     - echo "aaaaaaaaaa" > cattest.txt
     - cat cattest.txt
job2:
   stage: test2
   cache:
     paths:
       - cattest.txt
     key:
       key-extend
     policy: pull-push
   script:
     - cat cattest.txt
     - echo "bbb" >> cattest.txt
     - cat cattest.txt
job3:
   stage: test3
   cache:
     paths:
       - cattest.txt
     key:
       key-extend
     policy: pull-push
   script:
     - cat cattest.txt

效果图如上例

5. Cache 的禁用

如果整个 pipeline 配置全局的 cache,意味着每个 job 在没有特殊配置的情况下会使用全局的配置。但是如果某某个 job 并不使用到 cache,包括缓存文件的上传和下载,那么可以进行如下配置对整个 job 的 cache 禁用:

stages:
   - test
   - test2
cache:
   paths:
     - cattest.txt
     - cattest2.txt

job1:
   stage: test
   cache:
     paths:
       - cattest.txt
     key:
       key-cache-new1
    
   script:
     - cat cattest.txt
     - echo "aaaaaaaaaa" > cattest.txt
     - cat cattest.txt
job2:
   stage: test2
   cache: {}
   script:
     - cat cattest.txt
     
GitOps、新兴技术能力gitlab-ci/cd(六)cache机制插图11
job1
GitOps、新兴技术能力gitlab-ci/cd(六)cache机制插图12
job2

Where the caches are stored

All caches defined for a job are archived in a single cache.zip file. The runner configuration defines where the file is stored. By default, the cache is stored on the machine where GitLab Runner is installed. The location also depends on the type of executor.

Runner executorDefault path of the cache
ShellLocally, under the gitlab-runner user’s home directory: /home/gitlab-runner/cache/<user>/<project>/<cache-key>/cache.zip.
DockerLocally, under Docker volumes/var/lib/docker/volumes/<volume-id>/_data/<user>/<project>/<cache-key>/cache.zip.
Docker Machine (autoscale runners)The same as the Docker executor.

查看gitlab的pipeline源代码和cache挂载docker目录

方法一:

[root@docker volumes]# cd /var/lib/docker/volumes/
[root@docker volumes]# tree  -Ld 5
GitOps、新兴技术能力gitlab-ci/cd(六)cache机制插图13
cache存放目录

方法二:

通过研究发现runner的缓存文件存放在:/var/lib/docker/volumes/下以runner-{runnerid}-开头的文件夹中,
每个项目的缓存存放方式:runner-{runnerid}-projects-{projectid}-concurrent-{num}-cache-3c3f060a0374fc8bc39395164f415a70|c33bcaa1fd2c77edfc3893b41966cea8
以3c3f060a0374fc8bc39395164f415a70结尾的文件夹中存放的就是缓存文件,以c33bcaa1fd2c77edfc3893b41966cea8结尾的文件夹中存放的是代码源文件。

GitOps、新兴技术能力gitlab-ci/cd(六)cache机制插图14