모노레포 성능 문제 해결
모노레포의 성능 문제에 대한 다음 제안을 검토하세요.
git clone
또는 git fetch
시 느림
클론 및 페치에서 느림의 몇 가지 주요 원인이 있습니다.
높은 CPU 사용량
Gitaly 노드에서 CPU 사용량이 높은 경우, 특정 값을 필터링하여 클론에 의해 차지된 CPU 양을 확인할 수 있습니다.
특히, command.cpu_time_ms
필드는 클론 및 페치에 의해 얼마나 많은 CPU가 사용되는지를 나타낼 수 있습니다.
대부분의 경우, 서버 부하의 대부분은 클론 및 페치 중에 시작되는 git-pack-objects
프로세스에서 발생합니다. 모노레포는 종종 매우 바쁘며 CI/CD 시스템이 서버에 많은 클론 및 페치 명령을 보냅니다.
높은 CPU 사용량은 느린 성능의 흔한 원인입니다.
다음과 같은 상호 배타적이지 않은 원인이 있을 수 있습니다:
원인: 너무 많은 대형 클론
Gitaly에서 처리할 수 있는 대형 클론이 너무 많을 수 있습니다. Gitaly는 여러 요인으로 인해 따라가기가 어려울 수 있습니다:
- 저장소의 크기.
- 클론 및 페치의 양.
- CPU 용량 부족.
Gitaly에서 많은 대형 클론을 처리하도록 돕기 위해서는 다음과 같은 최적화 전략을 통해 Gitaly 서버의 부담을 줄여야 할 수 있습니다:
-
pack-objects-cache를 활성화하여
git-pack-objects
가 해야 하는 작업을 줄입니다. - CI/CD 설정에서 Git 전략을
clone
에서fetch
또는none
으로 변경합니다. - 테스트에서 태그가 필요하지 않은 경우 태그 페치 중지합니다.
- 가능할 경우 얕은 클론을 사용합니다.
또 다른 옵션은 Gitaly 서버의 CPU 용량을 늘리는 것입니다.
원인: 부실한 읽기 분포
Gitaly 클러스터에서 읽기 분포가 좋지 않을 수 있습니다.
대부분의 읽기 트래픽이 클러스터 전반에 걸쳐 분산되지 않고 기본 Gitaly 노드로 가고 있는지 확인하려면 읽기 분포 Prometheus 메트릭을 사용하세요.
보조 Gitaly 노드가 많은 트래픽을 받지 못한다면, 보조 노드가 지속적으로 동기화되지 않을 수 있습니다. 이 문제는 모노레포에서 더욱 악화됩니다.
모노레포는 종종 크고 바쁩니다. 이로 인해 두 가지 효과가 발생합니다. 첫째, 모노레포는 자주 푸시되고 많은 CI 작업이 실행됩니다. 브랜치를 삭제하는 등 쓰기 작업이 보조 노드에 대한 프록시 호출에서 실패할 수 있는 경우가 있습니다. 이는 보조 노드가 결국 따라잡을 수 있도록 Gitaly 클러스터에서 복제 작업을 유발합니다.
복제 작업은 본질적으로 보조 노드에서 기본 노드로의 git fetch
이며, 모노레포는 종종 매우 크기 때문에 이 페치가 오랜 시간이 걸릴 수 있습니다.
이전 복제 작업이 완료되기 전에 다음 호출이 실패하고 이러한 일이 계속 발생하면 모노레포가 보조 노드에서 지속적으로 뒤처지는 상태에 빠질 수 있습니다. 그러면 모든 트래픽이 기본 노드로 향하게 됩니다.
이러한 실패한 프록시 쓰기의 한 가지 이유는 Git의 $GIT_DIR/packed-refs
파일과 관련된 알려진 문제입니다. 파일에서 항목을 제거하려면 파일이 잠겨 있어야 하며, 이는 동시 삭제가 발생할 때 삭제가 실패하는 경합 조건을 유발할 수 있습니다.
GitLab의 엔지니어들은 참조 삭제를 배치 처리하려는 완화 조치를 개발했습니다.
다음 기능 플래그를 활성화하여 GitLab이 참조 삭제를 배치 처리할 수 있도록 하세요. 이러한 기능 플래그는 활성화하기 위해 다운타임이 필요하지 않습니다.
merge_request_cleanup_ref_worker_async
pipeline_cleanup_ref_worker_async
pipeline_delete_gitaly_refs_in_batches
merge_request_delete_gitaly_refs_in_batches
Epic 4220은 GitLab에서 RefTable 지원을 추가하는 것을 제안하며, 이는 장기 솔루션으로 간주됩니다.