- 중단 가능한 파이프라인
- Git fetch 캐싱
- 캐싱 전략
- 아티팩트 전략
- 컴포넌트 캐싱
cache-workhorse
cache-assets
compile-*-assets
- 스트립트된 이진 파일
CI 구성 성능
중단 가능한 파이프라인
기본적으로 모든 작업은 중단 가능하며, dont-interrupt-me
작업은 main
에서 자동으로 실행되며, 그 외에는 매뉴얼입니다.
Merge Request에 새로운 커밋을 푸시하더라도 실행 중인 파이프라인을 완료하려면 푸시하기 전에 dont-interrupt-me
작업을 시작해야 합니다.
Git fetch 캐싱
GitLab.com은 pack-objects 캐시를 사용하므로 동일한 파이프라인 ref의 동시 Git fetch는 Gitaly 서버에서 중복 처리되고 (항상) 캐시에서 제공됩니다(사용 가능한 경우).
이는 다음과 같은 이유로 잘 작동합니다:
- pack-objects 캐시는 GitLab.com의 모든 Gitaly 서버에서 활성화되어 있습니다.
- CI/CD Git 전략 설정은
gitlab-org/gitlab
에 대해 Git clone이므로, 모든 작업이 동일한 데이터를 가져오게 되어 캐시 히트 비율을 극대화합니다. - 얕은 클론을 사용하여 모든 작업에 대해 전체 Git 히스토리를 다운로드하는 것을 피합니다.
Gitaly에서 클론/페치하는 대신 artifact를 통해 리포지터리 가져오기
요즘 Gitaly에서 이러한 오류를 볼 수 있습니다: (관련 이슈 참조)
fatal: remote error: GitLab is currently unable to handle this request due to load.
GitLab.com이 pack-objects 캐시를 사용하더라도, 때때로 부하가 Gitaly가 처리하기에 여전히 너무 커지고 있으며 번개 떼 현상 또한 많은 작업이 동시에 리포지터리를 복제하고 있는 것에 대한 우려로 작용할 수 있습니다.
Gitaly의 부하를 완화하고 줄이기 위해 일부 작업을 한꺼번에 모두 Gitaly에서 복제하는 대신 작업으로 artifact에서 리포지터리를 가져오도록 변경했습니다.
현재 대부분의 RSpec 작업에 적용되며, 대부분 파이프라인에서 가장 많은 동시 작업을 갖고 있습니다. 이로 인해 또한 약간의 속도 향상이 이루어지며, 각 파이프라인에 대해 더 많은 artifact를 저장하는 비용이 발생하나, 복제보다 artifact에서 가져오는 것이 약간 더 빠릅니다.
2023-12-20의 숫자를 기반으로 한 RSpec 작업용 artifact에서 리포지터리 가져오기에 따르면, 추가 스토리지 비용은 각 파이프라인당 약 280M이었으며, 각 RSpec 작업당 15초를 절약했습니다.
이 작업은 다른 작업에 의존성이 없는 작업에는 적용하지 않습니다. 어떤 작업도 시작이 지연되는 것을 원치 않기 때문입니다.
이 행동은 변수 CI_FETCH_REPO_GIT_STRATEGY
로 제어할 수 있습니다:
-
none
으로 설정하면.repo-from-artifacts
를 사용하는 작업이 복제하는 대신 작업clone-gitlab-repo
에서 artifact에서 리포지터리를 가져옵니다. -
clone
으로 설정하면.repo-from-artifacts
를 사용하는 작업이 보통대로 리포지터리를 복제합니다. 이 경우에는 작업clone-gitlab-repo
가 실행되지 않습니다.
비활성화하려면 CI_FETCH_REPO_GIT_STRATEGY
를 clone
로 설정하고, 활성화하려면 CI_FETCH_REPO_GIT_STRATEGY
를 none
으로 설정하세요.
캐싱 전략
- 기본적으로 모든 작업은 캐시를 당겨야 합니다.
- 모든 작업은 빈 캐시로 통과해야 합니다. 다시 말해, 캐시는 작업 속도를 높이기 위한 것뿐입니다.
- 현재
.gitlab/ci/global.gitlab-ci.yml
에 여러 다른 캐시 정의가 정의되어 있으며 다음과 같은 고정된 키가 있습니다:.setup-test-env-cache
.ruby-cache
.static-analysis-cache
.rubocop-cache
.ruby-gems-coverage-cache
.ruby-node-cache
.qa-cache
.yarn-cache
-
.assets-compile-cache
(키에${NODE_ENV}
가 포함되어 있으므로 실제로 두 개의 다른 캐시입니다).
- 이러한 캐시 정의는 여러 원자적 캐시로 구성되어 있습니다.
- 2시간마다 실행되는
maintenance
예약된 파이프라인에서 실행되는 다음 작업만이 캐시에 푸시(즉, 업데이트)할 수 있습니다:-
.gitlab/ci/rails.gitlab-ci.yml
에 정의된update-setup-test-env-cache
. -
.gitlab/ci/rails.gitlab-ci.yml
에 정의된update-gitaly-binaries-cache
. -
.gitlab/ci/rails.gitlab-ci.yml
에 정의된update-rubocop-cache
. -
.gitlab/ci/qa.gitlab-ci.yml
에 정의된update-qa-cache
. -
.gitlab/ci/frontend.gitlab-ci.yml
에 정의된update-assets-compile-production-cache
. -
.gitlab/ci/frontend.gitlab-ci.yml
에 정의된update-assets-compile-test-cache
. -
.gitlab/ci/frontend.gitlab-ci.yml
에 정의된update-storybook-yarn-cache
.
-
- 이러한 작업은 또한 캐시 키를 업데이트하는 MR에서
pipeline:update-cache
라벨로 실행하도록 강제할 수 있습니다(캐시를 업데이트하는 MR에서 캐시를 미리 받아놓는 데 유용할 수 있습니다).
아티팩트 전략
작업에서 저장 및 검색되는 아티팩트를 최소화하여 업로드/다운로드 시간 및 비용, 아티팩트 저장 공간을 줄입니다.
컴포넌트 캐싱
GitLab의 일부 외부 컴포넌트(GitLab Workhorse 및 프런트엔드 에셋)는 테스트를 수행하기 위한 예비 단계로 소스에서 빌드해야 합니다.
cache-workhorse
이 MR 및 그 후
이 MR에서,
새로운 cache-workhorse
작업을 소개했습니다.
- 모든 GitLab.com
gitlab-org/gitlab
예약된 파이프라인에 자동으로 실행됩니다. - ‘workhorse/’ 폴더를 건드리는
master
커밋일 경우, 자동으로 실행됩니다. - 캐싱 관련 파일을 건드리는 GitLab.com의
gitlab-org
의 MR의 경우, 매뉴얼으로 실행됩니다.
이 작업은 GitLab 테스트 스위트에서 필요한 GitLab Workhorse 이진 파일을 포함하는 일반 패키지를 다운로드하려고 합니다(tmp/tests/gitlab-workhorse
하위에).
- 패키지 URL에서 404를 반환하는 경우:
-
scripts/setup-test-env
을 실행하여 GitLab Workhorse 이진 파일을 빌드합니다. - 그런 다음, 바이너리를 포함하는 아카이브를 만들고 일반 패키지로 업로드합니다.
-
- 그렇지 않은 경우, 패키지가 이미 존재하는 경우, 작업을 성공적으로 종료합니다.
또한 setup-test-env
작업을 다음과 같이 변경했습니다:
-
cache-workhorse
에 의해 빌드 및 업로드된 GitLab Workhorse 일반 패키지를 먼저 다운로드합니다. - 패키지가 성공적으로 검색되면 해당 내용이 올바른 폴더(예:
tmp/tests/gitlab-workhorse
)에 배치되어 나중에scripts/setup-test-env
가 실행될 때 이진 파일을 빌드하지 않도록 합니다. - 패키지 URL이 404를 반환하는 경우, 현재와 같이 동작이 변경되지 않습니다:
scripts/setup-test-env
의 일부로 GitLab Workhorse 이진 파일이 빌드됩니다.
git rev-parse HEAD:workhorse
)입니다.
cache-assets
이 MR에서, 세 가지 새로운 cache-assets:test
, cache-assets:test as-if-foss
, cache-assets:production
작업을 소개했습니다.
-
$CACHE_ASSETS_AS_PACKAGE == "true"
가 아닌 경우에는 절대로 실행되지 않습니다. - 모든 GitLab.com
gitlab-org/gitlab
예약된 파이프라인에 자동으로 실행됩니다. - 에셋 관련 폴더를 건드리는
master
커밋인 경우, 자동으로 실행됩니다. - 캐싱 관련 파일을 건드리는 GitLab.com의
gitlab-org
의 MR의 경우, 매뉴얼으로 실행됩니다.
이 작업은 GitLab 테스트 스위트에서 필요한 GitLab 컴파일된 에셋을 포함하는 일반 패키지를 다운로드하려고 합니다(app/assets/javascripts/locale/**/app.js
, 및 public/assets
하위에).
- 패키지 URL에서 404를 반환하는 경우:
-
bin/rake gitlab:assets:compile
을 실행하여 GitLab 에셋을 컴파일합니다. - 그런 다음, 에셋을 포함하는 아카이브를 만들고 일반 패키지로 업로드합니다. 패키지 버전은 에셋 폴더의 해시 합으로 설정됩니다.
-
- 그렇지 않은 경우, 패키지가 이미 존재하는 경우, 작업을 성공적으로 종료합니다.
compile-*-assets
compile-test-assets
, compile-test-assets as-if-foss
, compile-production-assets
작업을 다음과 같이 변경했습니다:
- 먼저 “원시” 캐시 에셋을 다운로드합니다. 이에는 다음이 포함됩니다:
- 컴파일된 에셋.
-
cached-assets-hash.txt
파일은 에셋이 의존하는 모든 소스 파일의SHA256
해시 합을 포함합니다. 이 파일에는 최악의 경우에도 모든 파일이 업데이트된 상태이므로 에셋이 더 자주 컴파일되는 것보다는 구식의 에셋을 사용하는 것이 나아합니다.파일은 에셋이 컴파일된 후에 생성됩니다.
- 그런 다음 현재 체크아웃된 브랜치의 소스 파일의
SHA256
해시 합을 계산합니다. 이후에는GITLAB_ASSETS_HASH
변수에 해시 합을 저장합니다. -
$CACHE_ASSETS_AS_PACKAGE == "true"
이면,cache-assets:*
에 의해 빌드 및 업로드된 일반 패키지를 다운로드합니다.- 캐시가 현재 체크아웃된 브랜치에 대해 최신 상태인 경우, 원시 캐시 및 패키지를 다운로드합니다. 패키지를 다운로드하지 않고도 최적화할 수 있습니다. 그러나 원시 캐시는 실제로 매우 자주 구식이므로 더 나빠질 수 있습니다.
-
assets_compile_script
함수를 실행하고, 이것 자체가assets:compile
Rake 작업을 실행합니다.이 작업은 에셋을 컴파일해야 할지 여부를 결정합니다. 그리고 $GITLAB_ASSETS_HASH
의
HEAD해시 합을
master의
cached-assets-hash.txt`와 비교합니다. - 해시가 동일하면 아무것도 컴파일하지 않고, 다른 경우에는 에셋을 컴파일합니다.
스트립트된 이진 파일
기본적으로 setup-test-env
는 연이어 발생하는 CI 작업의 아티팩트 다운로드를 가속화하고 저장 공간을 절약하기 위해 스트립트된 바이너리를 포함하는 아티팩트를 생성합니다.
스트립트된 바이너리에서의 크래시를 디버깅하기 쉽게 만들려면 setup-test-job
작업에서 strip_executable_binaries
라인에 주석을 달고 새로운 파이프라인을 시작하세요.