모노 레포 성능 문제 해결

monorepo의 성능 문제에 대한 권고 사항을 검토하세요.

git clone 또는 git fetch 중 느림

클론 및 페치 문제의 주요 원인이 몇 가지 있습니다.

CPU 사용률이 높음

Gitaly 노드의 CPU 사용률이 높은 경우 특정 값에 대한 필터링을 확인하여 클론에 사용된 CPU 양을 확인할 수도 있습니다.

특히 command.cpu_time_ms 필드는 클론 및 페치에 의해 사용된 CPU 양을 나타낼 수 있습니다.

대부분의 경우, 서버 부하의 대부분은 클론 및 페치 중에 시작되는 git-pack-objects 프로세스에서 생성됩니다. 모노 레포는 종종 매우 바쁘며 CI/CD 시스템은 서버에 많은 클론 및 페치 명령을 보냅니다.

높은 CPU 사용률은 느린 성능의 일반적인 원인입니다. 다음은 상호 배타적인 원인입니다. - Gitaly가 처리할 클론이 너무 많음. - Gitaly 클러스터의 부적절한 읽기 분산.

원인: 처리할 대형 클론이 너무 많음

Gitaly가 처리하기 어려울 정도로 많은 대형 클론이 있을 수 있습니다. Gitaly는 여러 요소로 인해 따라잡기 어려울 수 있습니다. - 저장소의 크기. - 클론 및 페치의 양. - CPU 용량의 부족.

많은 대형 클론을 처리하는 데 Gitaly를 돕기 위해 몇 가지 최적화 전략을 통해 Gitaly 서버에 부담을 줄일 수 있습니다. - pack-objects-cache를 사용하여 git-pack-objects의 작업을 줄입니다. - CI/CD 설정에서 Git 전략clone에서 fetch 또는 none으로 변경. - 테스트에 필요하지 않은 경우 태그 페치 중지. - 가능한 경우 얕은 클론 사용.

다른 옵션은 Gitaly 서버의 CPU 용량을 늘리는 것입니다.

원인: 부적절한 읽기 분산

Gitaly 클러스터에서 부적절한 읽기 분산이 있을 수 있습니다.

주요 Gitaly 노드가 대부분의 읽기 트래픽을 수신하지 않고 클러스터 전체에 분산되는지 확인하려면 읽기 분산 Prometheus 메트릭을 사용하세요.

별개 노드에는 트래픽이 거의 없는 경우, 별개 노드는 항상 동기화되지 않았을 수도 있습니다. 이 문제는 모노 레포에서 악화됩니다.

모노 레포는 종종 대형이자 바쁩니다. 이는 두 가지 효과를 가져옵니다. 첫째, 모노 레포는 자주 푸시되며 많은 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

장대 4220에서는 GitLab에 RefTable 지원을 추가하는 것을 제안하여 장기적인 솔루션으로 고려하고 있습니다.