- 인터럽트 가능한 파이프라인
- Git fetch 캐싱
- 캐싱 전략
- 아티팩트 전략
- 구성요소 캐싱
cache-workhorse
cache-assets
compile-*-assets
- 스트립된 바이너리
CI 구성 성능
인터럽트 가능한 파이프라인
기본적으로 모든 작업은 인터럽트 가능하며, main
에서 자동으로 실행되는 dont-interrupt-me
작업은 그 외에는 수동
입니다.
실행 중인 파이프라인이 병합 요청에 새 커밋을 푸시하더라도 완료되기를 원한다면, 푸시하기 전에 dont-interrupt-me
작업을 시작해야 합니다.
Git fetch 캐싱
GitLab.com은 pack-objects 캐시를 사용하기 때문에, 동일한 파이프라인 참조에 대한 동시 Git fetch는 Gitaly 서버에서 중복되지 않게 처리되며(항상) 캐시에서(사용 가능할 때) 제공됩니다.
이는 다음과 같은 이유로 잘 작동합니다:
- pack-objects 캐시는 GitLab.com의 모든 Gitaly 서버에서 활성화되어 있습니다.
- CI/CD Git 전략 설정에서
gitlab-org/gitlab
는 Git clone으로 설정되어 있어, 모든 작업이 동일한 데이터를 가져와 캐시 적중 비율을 극대화합니다. - 모든 작업에 대해 전체 Git 기록을 다운로드하지 않도록 얕은 클론을 사용합니다.
Gitaly에서 클론/페치하는 대신 아티팩트를 통해 리포지토리 가져오기
최근 Gitaly에서 다음과 같은 오류를 확인했습니다: (see the issue)
fatal: remote error: GitLab is currently unable to handle this request due to load.
GitLab.com이 pack-objects 캐시를 사용하고 있지만, 때때로 부하가 너무 많아 Gitaly가 이를 처리할 수 없고, 천둥 무리의 문제로 인해 많은 작업이 동시에 리포지토리를 클론하는 것도 우려되고 있습니다.
Gitaly의 부하를 완화하고 줄이기 위해, 일부 작업을 모든 클론 작업을 Gitaly에서 동시에 수행하는 대신 작업의 아티팩트에서 리포지토리를 가져오도록 변경했습니다.
현재 이것은 대부분의 RSpec 작업에 적용되며, 이는 대부분의 파이프라인에서 가장 많은 동시 작업을 가지고 있습니다. 또한 아티팩트에서 가져오는 것이 클론하는 것보다 약간 빠르기 때문에 속도도 약간 개선되었습니다. 이는 각 파이프라인에 대해 더 많은 아티팩트를 저장하는 대가로 이루어졌습니다.
2023-12-20의 RSpec 작업에 대한 아티팩트에서 리포지토리 가져오기 데이터에 따르면, 추가 저장 비용은 각 파이프라인에 대해 약 280M였으며, 각 RSpec 작업에 대해 15초를 절약했습니다.
의존성이 없는 작업에는 이 방법을 적용하지 않으며, 이유는 어떤 작업의 시작을 지연시키고 싶지 않기 때문입니다.
이 동작은 변수 CI_FETCH_REPO_GIT_STRATEGY
로 제어할 수 있습니다:
-
none
으로 설정하면.repo-from-artifacts
를 사용하는 작업이clone-gitlab-repo
작업의 아티팩트에서 리포지토리를 가져옵니다. -
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
.
-
- 이러한 작업은
pipeline:update-cache
레이블이 있는 병합 요청에서 강제로 실행할 수도 있습니다(이는 캐시 키를 업데이트하는 MR에서 캐시를 워밍업하는 데 유용할 수 있습니다).
아티팩트 전략
업로드/다운로드 시간과 비용을 줄이며 아티팩트 저장소를 최소화하기 위해 작업에서 저장되고 검색되는 아티팩트를 제한합니다.
구성요소 캐싱
일부 외부 구성 요소(예: GitLab Workhorse 및 프론트엔드 자산)는 테스트를 실행하기 위한 초기 단계로 소스에서 빌드해야 합니다.
cache-workhorse
이 MR와
이 MR에서는 다음을 수행하는 새로운 cache-workhorse
작업을 도입했습니다:
- 모든 GitLab.com
gitlab-org/gitlab
예약 파이프라인에 대해 자동으로 실행됩니다. -
workhorse/
폴더에 영향을 주는 모든master
커밋에 대해 자동으로 실행됩니다. - 캐싱 관련 파일에 영향을 주는 GitLab.com의
gitlab-org
의 MR에 대해서는 수동입니다.
이 작업은 GitLab 테스트 스위트( tmp/tests/gitlab-workhorse
아래)에서 필요한 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를 반환하면, 현재와 비교할 때 동작은 변경되지 않으며, GitLab Workhorse 바이너리는
scripts/setup-test-env
의 일부로 빌드됩니다.
참고:
패키지 버전은 workhorse 트리 SHA입니다(예: 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-production-assets
작업을 다음과 같이 변경했습니다:
-
먼저 “네이티브” 캐시 자산을 다운로드합니다. 이 자산에는 다음이 포함됩니다:
-
모든 소스 파일의
SHA256
해시를 포함하는cached-assets-hash.txt
파일입니다.이 파일 목록은 비관적인 목록이며 자산은 일부 파일에 의존하지 않을 수 있습니다. 최악의 경우 자산을 더 자주 컴파일하게 되며, 이는 구식 자산을 사용하는 것보다 낫습니다.
이 파일은 자산이 컴파일된 후 생성됩니다.
-
그런 다음 자산이 의존하는 모든 소스 파일의
SHA256
해시를 현재 체크아웃된 브랜치에서 계산합니다. 해시를GITLAB_ASSETS_HASH
변수에 저장합니다. -
$CACHE_ASSETS_AS_PACKAGE == "true"
인 경우,cache-assets:*
에서 생성되고 업로드된 일반 패키지를 다운로드합니다.- 체크아웃된 브랜치에 대한 캐시가 최신인 경우, 네이티브 캐시 및 캐시 패키지를 다운로드합니다. 일반 패키지를 다운로드하지 않고 네이티브 캐시를 다운로드하는 방식으로 최적화할 수 있지만, 네이티브 캐시는 실제로 매우 자주 구식이 되기 때문에 매 2시간마다만 재구성됩니다.
-
assets_compile_script
함수를 실행합니다,이는 자체적으로 실행합니다
이 작업은 자산을 컴파일할 필요가 있는지 여부를 결정하는 역할을 합니다.
이는
$GITLAB_ASSETS_HASH
의HEAD
SHA256
해시와cached-assets-hash.txt
의master
해시를 비교합니다. -
해시가 같으면 아무 것도 컴파일하지 않습니다. 다르면 자산을 컴파일합니다.
스트립된 바이너리
기본적으로, setup-test-env
는 다음 CI 작업의 아티팩트 다운로드를 위해 스토리지를 절약하고 속도를 높이기 위해 스트립된 바이너리를 포함하는 아티팩트를 생성합니다. https://gitlab.com/gitlab-org/gitlab/-/issues/442029#note_1775193538
스트립된 바이너리에서 충돌을 디버깅하는 것을 쉽게 하려면 setup-test-job
작업에서 strip_executable_binaries
가 있는 줄의 주석을 제거하고 새 파이프라인을 시작하십시오.