Gitaly 및 Gitaly 클러스터

Tier: Free, Premium, Ultimate Offering: Self-Managed

Gitaly은 Git 리포지터리에 대한 고수준의 RPC 액세스를 제공합니다. GitLab에서 사용되어 소스 브랜치에서 Git 데이터를 읽고 쓰는 데 사용됩니다.

Gitaly는 모든 GitLab 설치에 존재하며 Git 리포지터리의 저장 및 검색을 조정합니다. Gitaly는 다음과 같을 수 있습니다:

  • 단일 인스턴스 Linux 패키지 설치(하나의 머신에서 GitLab 전체)에서 작동하는 백그라운드 서비스.
  • 스케일링 및 가용성 요구에 따라 완전한 클러스터 구성으로 분리되어 구성된 별개의 인스턴스.

Gitaly는 클라이언트-서버 아키텍처를 구현합니다.

Gitaly는 GitLab의 Git 리포지터리 액세스만 관리합니다. 다른 유형의 GitLab 데이터는 Gitaly를 통해 액세스되지 않습니다.

GitLab은 구성된 리포지터리 스토리지를 통해 리포지터리에 액세스합니다. 각 새 리포지터리는 구성된 가중치에 따라 서로 다른 리포지터리 스토리지 중 하나에 저장됩니다. 각 리포지터리 스토리지는 다음 중 하나입니다:

  • 리포지터리 경로를 사용하여 리포지터리에 직접 액세스하는 Gitaly 리포지터리, 각 리포지터리가 단일 Gitaly 노드에 저장되는 방식으로 모든 요청이 이 노드로 라우팅됨.
  • Gitaly 클러스터가 제공하는 가상 리포지터리, 각 리포지터리가 오류 허용을 위해 여러 Gitaly 노드에 저장될 수 있는 방식. Gitaly 클러스터에서:
    • 읽기 요청은 여러 Gitaly 노드 사이에 분산되어 성능을 향상시킬 수 있음.
    • 쓰기 요청은 리포지터리 복제본에게 브로드캐스트됨.

Gitaly 클러스터 배포 전

Gitaly 클러스터는 오류 허용의 장점을 제공하지만 설정 및 관리의 추가 복잡성을 수반합니다. Gitaly 클러스터를 배포하기 전에 다음을 검토하세요:

아직 Gitaly 클러스터로 이전하지 않았다면 두 가지 옵션이 있습니다:

  • 분할된 Gitaly 인스턴스.
  • Gitaly 클러스터.

질문이 있으시면 고객 성공 담당자 또는 고객 지원팀에 문의하세요.

알려진 문제

다음 표는 Gitaly 클러스터 사용에 영향을 미치는 현재 알려진 문제를 요약한 것입니다. 이러한 문제의 현재 상태에 대한 자세한 내용은 참조된 이슈 및 에픽을 확인하세요.

문제 요약 피하는 방법
Gitaly 클러스터 + Geo - 동기화 실패 문제 다시 시도 Geo 보조 사이트에서 Gitaly 클러스터를 사용하는 경우, 동기화에 실패한 리포지터리는 Geo가 다시 동기화를 시도할 때 계속 실패할 수 있습니다. 이 상태에서 복구하려면 매뉴얼 단계 실행에 대한 지원이 필요합니다. GitLab 15.0에서 15.2까지 Geo 주 사이트에서 gitaly_praefect_generated_replica_paths 피처 플래그을 활성화하세요. GitLab 15.3에서 기본적으로 이 피처 플래그가 활성화됩니다.
마이그레이션을 실시한 후 Praefect가 데이터를 데이터베이스에 삽입하지 못하는 문제 데이터베이스가 완료된 마이그레이션과 함께 현재 상태를 유지하지 않으면 Praefect 노드는 표준 작업을 수행할 수 없습니다. Praefect 데이터베이스가 모든 마이그레이션이 완료된 상태로 작동 중인지 확인하세요(예: /opt/gitlab/embedded/bin/praefect -config /var/opt/gitlab/praefect/config.toml sql-migrate-status를 실행하면 적용된 모든 마이그레이션의 디렉터리이 표시됩니다). 지원팀에 업그레이드 지원을 요청하여 업그레이드 계획을 검토받으세요.
실행 중인 클러스터에서 스냅숏에서 Gitaly 클러스터 노드를 복원하는 경우 Gitaly 클러스터가 일관된 상태로 실행되기 때문에 한 노드를 복원하면 클러스터가 노드 데이터와 다른 노드 데이터를 조화시키지 못할 수 있습니다. 단일 Gitaly 클러스터 노드를 백업 스냅숏에서 복원하지 마세요. 복원해야 하는 경우:

1. GitLab을 종료합니다.
2. 동시에 모든 Gitaly 클러스터 노드를 스냅숏합니다.
3. Praefect 데이터베이스의 데이터베이스 덤프를 가져옵니다.
Kubernetes, Amazon ECS 등에서 실행 시 제한 사항 Praefect(Gitaly 클러스터)은 지원되지 않으며 Gitaly에는 알려진 제한 사항이 있습니다. 자세한 내용은 epic 6127을 참조하세요. 참조 아키텍쳐를 사용하세요.

스냅숏 백업 및 복구 제한

Gitaly 클러스터는 스냅숏 백업을 지원하지 않습니다. 스냅숏 백업은 Praefect 데이터베이스가 디스크 리포지터리와 동기화가 되지 않게 만들 수 있습니다. 복원 중에 Praefect가 Gitaly 디스크 정보의 복제 메타데이터를 다시 작성하는 방식 때문에 공식 백업 및 복원 Rake 작업을 사용해야 합니다.

증분 백업 방법은 Gitaly 클러스터 백업을 가속화하는 데 사용될 수 있습니다.

양측 방법을 모두 사용할 수 없는 경우 복구 지원을 받기 위해 고객 지원팀에 문의하세요.

문제 또는 제한 사항이 발생한 Gitaly 클러스터의 조치 방법

즉시 복원 또는 회복을 위해 고객 지원팀에 문의하세요.

디스크 요구 사항

Gitaly 및 Gitaly 클러스터는 고 I/O 기반 프로세스이므로 효율적으로 수행하기 위해 빠른 로컬 스토리지를 필요로 합니다. 따라서, 모든 Gitaly 노드가 반드시 솔리드 스테이트 드라이브(SSD)를 사용하는 것을 강력히 권장합니다.

이러한 SSD는 최소한 다음과 같아야 합니다:

  • 읽기 작업의 경우 초당 8,000개의 입력/출력 연산(IOPS).
  • 쓰기 작업의 경우 2,000개의 IOPS.

이러한 IOPS 값은 초기 권장 사항이며, 환경의 작업 부하에 따라 더 크거나 작은 값으로 조정될 수 있습니다. 환경을 클라우드 제공업체에서 실행하는 경우 올바른 IOPS 설정 방법에 대해서는 해당 문서를 참조하세요.

Gitaly 및 Gitaly 클러스터에서는 성능 및 일관성 이유로 리포지터리 데이터에 대해 로컬 스토리지만 지원됩니다. NFS클라우드 기반 파일 시스템과 같은 대안은 지원되지 않습니다.

리포지터리 직접 액세스

Gitaly는 지속적으로 개선되고 변경되고 있으므로 Git 리포지터리를 직접 액세스하는 것을 권장하지 않습니다. 이러한 개선사항으로 인해 귀하의 가정이 무효화되어 성능 저하, 불안정성 및 데이터 손실이 발생할 수 있습니다. 예를 들어:

  • Gitaly에는 info/refs 광고 캐시와 같은 최적화 기능이 있으며 공식 gRPC 인터페이스를 사용하여 리포지터리에 대한 액세스를 제어하고 모니터링합니다.
  • Gitaly 클러스터에는 오류 허용 및 분산 읽기와 같은 최적화 기능이 있으며, 리포지터리 상태를 결정하기 위해 gRPC 인터페이스와 데이터베이스에 의존합니다.
caution
Git 리포지터리에 직접 액세스하는 것은 고객이 직접 책임지며 지원되지 않습니다.

Gitaly

다음은 Gitaly를 직접 액세스하도록 구성된 GitLab을 보여줍니다:

샤드 예시

이 예에서:

  • 각 리포지터리는 storage-1, storage-2, 또는 storage-3 중 하나의 Gitaly 리포지터리에 저장됩니다.
  • 각 리포지터리는 Gitaly 노드에서 서비스를 받습니다.
  • 세 개의 Gitaly 노드는 파일 시스템에 데이터를 저장합니다.

Gitaly 아키텍처

다음은 Gitaly 클라이언트-서버 아키텍처를 설명합니다:

flowchart TD 서브그래프 Gitaly 클라이언트 A[GitLab Rails] B[GitLab Workhorse] C[GitLab Shell] D[...] end 서브그래프 Gitaly E[Git 통합] end F[로컬 파일 시스템] A -- gRPC --> Gitaly B -- gRPC--> Gitaly C -- gRPC --> Gitaly D -- gRPC --> Gitaly E --> F

Gitaly 구성

Gitaly는 리눅스 패키지 설치 시 미리 구성되어 있으며, 이는 20 RPS / 1,000 사용자까지 적합한 구성입니다. 다음 사항에 대해:

매일 Git 쓰기 작업을 수행하는 2,000명 이상의 활성 사용자를 대상으로 한 GitLab 설치는 Gitaly 클러스터를 사용하는 것이 가장 적합할 수 있습니다.

Gitaly CLI

gitaly 명령어는 Gitaly 관리자를 위한 추가 하위 명령을 제공하는 명령줄 인터페이스입니다. 예를 들어, Gitaly CLI는 다음을 수행하는 데 사용됩니다:

기타 하위 명령에 대한 자세한 내용은 gitaly --help를 실행하십시오.

리포지터리 백업

GitLab 이외의 도구를 사용하여 리포지터리를 백업하거나 동기화할 때 리포지터리 데이터를 복사하는 동안 쓰기 방지해야 합니다.

번들 URI

Gitaly와 함께 Git 번들 URI를 사용할 수 있습니다. 자세한 내용은 번들 URI 문서를 참조하십시오.

Gitaly 클러스터

Git 리포지터리는 GitLab의 Gitaly 서비스를 통해 제공되며, GitLab의 작동에 중요합니다. 사용자 수, 리포지터리 수, 및 활동이 증가함에 따라 Gitaly를 적절하게 확장하는 것이 중요합니다.

  • 리소스 고갈로 인해 Git, Gitaly 및 GitLab 애플리케이션 성능이 저하되지 않도록 하기 위해 Git에 제공되는 CPU 및 메모리 리소스를 늘리십시오.
  • 쓰기 작업 실패를 유발하는 리포지터리 한계에 도달하지 않도록하기 위해 사용 가능한 리포지터리를 확장하십시오.
  • 프로덕션에 변경 사항을 배포하지 못하게 하는 서비스 저하가 발생할 경우 Git을 미션 크리티컬로 고려하십시오.

Gitaly는 클러스터 구성에서 실행하여 다음을 수행할 수 있습니다:

  • Gitaly 서비스 확장.
  • 오류 허용성 향상.

이 구성에서 모든 Git 리포지터리는 클러스터의 여러 Gitaly 노드에 저장될 수 있습니다.

Gitaly 클러스터 사용으로 인해 장애 허용성이 향상됩니다:

  • 따뜻한 스탠바이 Gitaly 노드로의 쓰기 작업 복제.
  • Gitaly 노드 장애 감지.
  • 가용한 Gitaly 노드로의 Git 요청 자동 라우팅.
note
Gitaly 클러스터의 기술 지원은 GitLab Premium 및 Ultimate 고객에게 한정됩니다.

다음은 Gitaly의 storage-1에 액세스하여 구성된 GitLab을 보여줍니다:

클러스터 예시

이 예에서:

  • 리포지터리는 storage-1이라는 가상 스토리지에 저장됩니다.
  • 세 개의 Gitaly 노드가 storage-1 액세스를 제공합니다: gitaly-1, gitaly-2, 및 gitaly-3.
  • 세 개의 Gitaly 노드는 세 개의 별도 해시 저장 위치에서 데이터를 공유합니다.
  • 복제 팩터3입니다. 각 리포지터리의 복사본이 유지됩니다.

단일 노드 장애를 가정하면 Gitaly 클러스터의 가용성 목표는 다음과 같습니다:

  • RPO(복구 지점 목표): 1분 미만.

    쓰기 작업은 비동기적으로 복제됩니다. 최근 프로모션된 주 마스터에 복제되지 않은 쓰기 작업은 손실됩니다.

    강력한 일관성은 어떤 경우에도 손실을 방지합니다.

  • RTO(복구 시간 목표): 10초 미만. 중단은 Praefect 노드마다 1초마다 수행되는 건강한 체크에 의해 감지됩니다. 장애 조치를 취하려면 각 Praefect 노드에서 연속된 열 번의 실패한 건강한 체크가 필요합니다.

RPO 및 RTO의 개선 사항은 에픽 8903에서 제안됩니다.

caution
클러스터 전체 장애가 발생하면 재해 복구 계획을 실행해야 합니다. 이는 위에서 논의된 RPO 및 RTO에 영향을 미칠 수 있습니다.

Geo와의 비교

Gitaly 클러스터와 Geo 모두 중복성을 제공합니다. 그러나:

  • Gitaly 클러스터는 데이터 저장을 위한 장애 허용성을 제공하며 사용자에게는 투명합니다. 사용자가 Gitaly 클러스터를 사용하는지 여부를 인식하지 못합니다.
  • Geo는 복제재해 복구를 제공하여 전체 GitLab 인스턴스에 대해 사용자가 사용 중인지 알 수 있습니다. Geo는 Git 데이터를 포함하여 여러 데이터 유형을 복제합니다.

다음 표는 Gitaly 클러스터와 Geo의 주요 차이점을 보여줍니다:

도구 노드 위치 지연 허용성 장애 조치 일관성 중복성 제공
Gitaly 클러스터 다수 단일 1초 미만, 이상적으로 단일 자릿수 밀리초 자동 강력함 데이터 저장
Geo 다수 다중 1분까지 매뉴얼 결과적 전체 GitLab 인스턴스

자세한 내용은 다음을 참조하십시오:

가상 스토리지

가상 스토리지를 사용하면 GitLab의 단일 리포지터리 저장이 가능해지며 이는 리포지터리 관리를 간소화합니다.

Gitaly 클러스터를 사용하는 가상 스토리지는 일반적으로 직접 Gitaly 저장 구성을 대체할 수 있습니다. 그러나 각 리포지터리를 여러 Gitaly 노드에 저장해야하기 때문에 추가 저장 공간이 필요합니다. Gitaly 클러스터 가상 스토리지를 사용하는 이점은 다음과 같습니다:

  • 각 Gitaly 노드가 모든 리포지터리의 사본을 가지고 있기 때문에 장애 허용성이 향상됩니다.
  • 읽기 부하가 Gitaly 노드에 분산되므로 샤드별 피크 부하를 위해 과다한 공급이 필요하지 않아 리소스 이용률이 향상됩니다.
  • 성능을 위한 매뉴얼 리밸런싱이 필요하지 않으며, 읽기 부하가 Gitaly 노드에 분산되기 때문에 관리가 간소화됩니다.
  • 매우 큰 GitLab 인스턴스에 대한 유연성을 제공하려면 이 이슈에서 추적된 가변 복제 팩터가 필요합니다.

표준 Gitaly 리포지터리처럼 가상 스토리지를 샤딩할 수 있습니다.

리포지터리 레이아웃

caution
리포지터리 레이아웃은 Gitaly Cluster의 내부 세부 정보로, 릴리스간 안정성이 보장되지 않습니다. 여기에 있는 정보는 오직 정보 제공 및 디버깅을 위한 것입니다. 디스크에서 리포지터리에 직접적인 변경을 가하는 것은 지원되지 않으며, 시스템의 손상이나 변경 내용이 덮어씌워지는 결과를 초래할 수 있습니다.

Gitaly Cluster의 가상 리포지터리는 단일 리포지터리처럼 보이는 추상화를 제공하지만 실제로 여러 물리적 리포지터리로 구성되어 있습니다. Gitaly Cluster는 각 물리적 리포지터리로 각 작업을 복제해야 합니다. 작업은 몇몇 물리적 리포지터리에서 성공할 수 있지만, 다른 리포지터리에서는 실패할 수 있습니다.

부분 적용된 작업은 기타 작업에 문제를 일으키고 시스템을 회복할 수 없는 상태로 남길 수 있습니다. 이러한 유형의 문제를 피하기 위해서는 각 작업이 완전히 적용되거나 아예 적용되지 않아야 합니다. 작업의 이러한 특성을 원자성이라고 합니다.

GitLab은 리포지터리 스토리지의 리포지터리 레이아웃을 제어합니다. GitLab은 리포지터리 스토리지에게 리포지터리를 생성, 삭제 및 이동할 위치를 지시합니다. 이러한 작업은 여러 물리적 리포지터리에 적용될 때 원자성 문제를 일으킬 수 있습니다. 예를 들어:

  • GitLab이 리포지터리를 삭제하는 동안 그 중 하나의 복제본이 사용할 수 없는 상태인 경우.
  • GitLab이 나중에 리포지터리를 다시 생성하는 경우.

이 결과로, 삭제 시 사용할 수 없었던 낡은 복제본이 리포지터리 재생성을 방해하고 복제본이 만들어지지 못하게 할 수 있습니다.

원자성 문제는 지난 시간 동안 여러 문제를 일으켰으며 다음과 같은 상황에서 문제를 일으켰습니다:

  • Gitaly Cluster에 이중화 동기화.
  • 백업 복원.
  • 리포지터리 스토리지간의 이동.

Gitaly Cluster는 이러한 작업의 원자성을 보장하기 위해서 특별한 레이아웃으로 디스크에 리포지터리를 저장하여 부분 적용된 작업으로 인해 발생할 수 있는 충돌을 방지합니다.

클라이언트 생성 복제본 경로

리포지터리는 Gitaly 클라이언트에 의해 상대적 경로에 저장되며, 이 경로는 @cluster 접두사로 시작하지 않는 것으로 식별될 수 있습니다. 상대적인 경로는 해시된 리포지터리 스키마를 따릅니다.

Praefect 생성 복제본 경로

Gitaly Cluster가 리포지터리를 생성할 때, 리포지터리에 고유하고 영구적인 ID인 _리포지터리 ID_를 할당합니다. 리포지터리 ID는 Gitaly Cluster 내부에만 존재하며 GitLab의 다른 ID와 관련이 없습니다. 리포지터리가 Gitaly Cluster에서 제거되고 나중에 다시 이동되면, 리포지터리는 새로운 리포지터리 ID가 할당되고 Gitaly Cluster의 관점에서는 다른 리포지터리가 됩니다. 리포지터리 ID의 순서는 항상 증가하지만 순서에는 빈 칸이 있을 수 있습니다.

리포지터리 ID는 클러스터의 모든 리포지터리의 공통 복제본 경로인 _복제본 경로_를 파생하기 위해 사용됩니다. 리포지터리의 복제본은 모두 리포지터리 ID 별로 동일한 복제본 경로에 저장됩니다. 복제본 경로는 상대 경로에서 구분되며:

  • 상대 경로는 Gitaly 클라이언트가 그들에게 고유한 가상 리포지터리와 함께 식별하는 리포지터리의 이름입니다.
  • 복제본 경로는 물리적인 리포지터리의 실제 경로입니다.

Praefect는 클라이언트 요청을 처리할 때 물리적인 리포지터리의 실제 리포지터리 (리포지터리, 복제본 경로) 식별자로부터 가상 (가상 리포지터리, 상대 경로) 식별자로 변환합니다.

객체 풀의 복제본은 @cluster/pools/<xx>/<xx>/<리포지터리 ID> 형식을 갖습니다. 객체 풀은 다른 리포지터리와 다른 디렉터리에 저장되어 있으며, Gitaly에서 식별되어 가지치기의 일부로 삭제되는 것을 피해야 합니다. 객체 풀을 가치지기하는 것은 연결된 리포지터리에서 데이터 손실을 일으킬 수 있습니다.

다른 리포지터리의 형식은 @cluster/repositories/<xx>/<xx>/<리포지터리 ID>입니다.

예를 들어, @cluster/repositories/6f/96/54771.

복제본 경로의 마지막 구성요소 54771은 리포지터리 ID입니다. 이를 사용하여 디스크에서 리포지터리를 식별할 수 있습니다.

<xx>/<xx>은 리포지터리 ID의 문자열 표현의 SHA256 해시의 처음 네 자리 16진수 입니다. 이 자리수는 리포지터리를 과도하게 커져서 어떤 파일 시스템에서 문제를 일으킬 수 있는 과도하게 큰 디렉터리를 피하기 위해 리포지터리를 균등하게 분배하기 위해 사용됩니다. 이 경우, 547716f960ab01689464e768366d3315b3d3b2c28f38761a58a70110554eb04d582f7을 해싱하기 때문에 처음 네 자리는 6f96입니다.

디스크의 리포지터리 식별

praefect metadata 하위 명령을 사용하여 다음을 수행할 수 있습니다:

  • 메타데이터 리포지터리에서 리포지터리의 가상 리포지터리 및 상대 경로를 검색합니다. 해싱된 리포지터리 경로를 얻은 후, Rails 콘솔을 사용하여 프로젝트 경로를 검색할 수 있습니다.
  • 리포지터리가 저장된 클러스터 내의 위치를 확인하려면:
    • 가상 리포지터리와 상대 경로.
    • 리포지터리 ID.

디스크의 리포지터리에는 리포지터리의 메타데이터가 삭제되었더라도, 프로젝트 경로가 Git 구성 파일에 포함되어 있습니다. 구성 파일을 사용하여 리포지터리의 메타데이터가 삭제되었더라도 프로젝트 경로를 결정할 수 있습니다. hashed storage의 설명서의 지침을 따르세요.

작업의 원자성

Gitaly Cluster는 리포지터리 생성, 삭제 및 이동 작업의 원자성을 보장하기 위해 스토리지 레이아웃과 함께 PostgreSQL 메타데이터 리포지터리를 사용합니다. 디스크 작업은 여러 리포지터리에 걸쳐 원자적으로 적용될 수 없습니다. 그러나 PostgreSQL은 메타데이터 작업의 원자성을 보장합니다. Gitaly Cluster는 실패한 작업이 메타데이터를 항상 일관되게 남도록 작업을 모델링합니다. 디스크는 성공한 작업 이후에도 낡은 상태를 포함할 수 있습니다. 이 상황은 예상대로 남아있으며 남은 상태는 미래 작업에 방해가 되지 않지만 정리가 수행될 때까지 불필요하게 디스크 공간을 사용할 수 있습니다.

백그라운드 크롤러가 리포지터리의 남은 항목을 정리하는 작업이 진행 중입니다.

리포지터리 생성

리포지터리를 생성할 때, Praefect는 다음을 수행합니다:

  1. PostgreSQL에서 리포지터리 ID를 예약하며, 두 개의 창고가 동일한 ID를 받지 못하도록 되어 있습니다.
  2. Gitaly 리포지터리에 리포지터리 ID에서 파생된 복제본 경로에 복제본 생성.
  3. 리포지터리가 디스크에 성공적으로 생성된 후 메타데이터 레코드를 생성합니다.

동시 실행되는 두 작업이 동일한 리포지터리를 생성하더라도, 해당 리포지터리는 리포지터리에서 다른 디렉터리에 저장되어 충돌하지 않습니다. 첫 번째로 완료된 작업은 메타데이터 레코드를 생성하고 다른 작업은 “이미 존재함” 오류로 실패합니다. 실패한 생성은 리포지터리에 남아있습니다. 백그라운드 크롤러가 리포지터리의 남은 항목을 정리하는 작업이 진행 중입니다.

리포지터리 ID는 PostgreSQL의 repositories_repository_id_seq에서 생성됩니다. 위의 예에서, 실패한 작업은 한 번의 리포지터리 ID를 가져가지만 성공적으로 리포지터리를 생성하지 않았습니다. 실패한 리포지터리 생성은 리포지터리 ID에 공백을 유발할 수 있습니다.

리포지터리 삭제

리포지터리는 메타데이터 레코드를 제거함으로써 삭제됩니다. 메타데이터 레코드가 삭제되는 즉시 리포지터리는 논리적으로 존재하지 않게 됩니다. PostgreSQL은 제거의 원자성을 보장하며 동시 삭제는 “찾을 수 없음” 오류로 실패합니다. 메타데이터 레코드를 성공적으로 삭제한 후 Praefect는 스토리지에서 레플리카를 제거하려고 시도합니다. 이 작업이 실패할 수 있으며 스토리지에 잔여 상태가 남을 수 있습니다. 잔여 상태는 최종적으로 정리됩니다.

리포지터리 이동

Gitaly와 달리 Gitaly Cluster는 리포지터리를 스토리지에서 실제로 이동하지 않고 메타데이터 리포지터리에서 리포지터리의 상대 경로를 업데이트하여 가상으로 이동시킵니다.

컴포넌트

Gitaly Cluster는 여러 컴포넌트로 구성됩니다.

  • 로드 밸런서는 요청을 분산하고 Praefect 노드에 접근할 수 있도록 내결함성을 제공합니다.
  • Praefect 노드는 클러스터를 관리하고 Gitaly 노드로의 요청을 라우팅하는 역할을 합니다.
  • PostgreSQL 데이터베이스는 클러스터 메타데이터를 유지하며 PgBouncer는 Praefect의 데이터베이스 연결을 풀링하는 데 권장됩니다.
  • 리포지터리 및 Git 액세스를 제공하기 위한 Gitaly 노드.

아키텍처

Praefect는 Gitaly의 라우터 및 트랜잭션 관리자이며 Gitaly Cluster를 실행하는 데 필수적인 컴포넌트입니다.

아키텍처 다이어그램

더 많은 정보를 보려면 Gitaly 고가용성(HA) 설계를 참조하세요.

기능

Gitaly Cluster는 다음과 같은 기능을 제공합니다.

수평으로 읽기 분산을 포함한 개선을 위해 Gitaly Cluster 에픽을 참조하세요.

분산 읽기

Gitaly Cluster는 가상 리포지터리로 구성된 Gitaly 노드 간의 읽기 작업을 분산합니다.

ACCESSOR 옵션으로 표시된 모든 RPC는 최신 및 건강한 Gitaly 노드로 리디렉션이 됩니다. 예를 들어, GetBlob.

이 문맥에서의 “최신”은 다음을 의미합니다:

  • 이 Gitaly 노드에 대한 레플리케이션 작업이 예약되어 있지 않습니다.
  • 마지막 레플리케이션 작업이 “완료됨” 상태에 있습니다.

만약 최신 상태의 노드가 없는 경우 기본 노드가 요청을 처리하기로 선택됩니다. - 최신 상태의 노드가 존재하지 않음. - 노드 선택 중에 다른 오류가 발생함.

대용량 및 많이 수정된 리포지터리(예: 멀티기가바이트 모노레포)를 보유하고 있다면, 변경 사항이 Praefect가 이차 노드로 복제하기 전에 더 빨리 들어오는 경우 기본 노드가 대부분 또는 모든 요청을 처리할 수 있습니다. 이런 경우 CI/CD 작업 및 다른 리포지터리 트래픽은 기본 노드의 용량에 의해 병목현상을 겪게 됩니다.

Prometheus를 사용하여 읽기 분산을 모니터링할 수 있습니다.

강력한 일관성

Gitaly Cluster는 모든 건강하고 최신 상태의 레플리카로 변경사항을 동기적으로 기록하여 강력한 일관성을 제공합니다. 트랜잭션이 발생할 때 레플리카가 오래된 경우 또는 건강하지 않은 경우, 쓰기 작업은 비동기적으로 레플리카에 복제됩니다.

강력한 일관성은 주요한 복제 방법입니다. 일부 작업은 강력한 일관성 대신 레플리케이션 작업(최종적 일관성)을 사용합니다. 자세한 내용은 강력한 일관성 에픽을 참조하세요.

강력한 일관성을 사용할 수 없는 경우 Gitaly Cluster는 최종적인 일관성을 보장합니다. 이 경우 Gitaly Cluster는 각 쓰기 작업을 기본 Gitaly 노드에 쓴 후에 등록된 두 번째 Gitaly 노드로 복제합니다.

강력한 일관성을 모니터링하는 자세한 내용은 Gitaly Cluster Prometheus 메트릭 문서를 참조하세요.

레플리케이션 팩터

레플리케이션 팩터는 Gitaly Cluster가 특정 리포지터리의 복제본을 유지하는 수입니다. 더 높은 레플리케이션 팩터는 다음을 제공합니다:

  • 더 나은 중복성 및 읽기 작업의 분산화
  • 더 높은 리포지터리 비용

기본적으로 Gitaly Cluster는 가상 리포지터리의 모든 스토리지에 리포지터리를 복제합니다.

구성 정보는 레플리케이션 팩터를 구성에서 확인할 수 있습니다.

Gitaly Cluster 구성

Gitaly Cluster를 구성하는 자세한 내용은 Gitaly Cluster 구성을 참조하세요.

Gitaly Cluster 업그레이드

Gitaly Cluster를 업그레이드하는 방법은 다운타임 없는 업그레이드 설명서를 따르세요.

이전 버전으로 Gitaly Cluster 다운그레이드

Gitaly Cluster를 이전 버전으로 롤백해야 하는 경우 일부 Praefect 데이터베이스 마이그레이션이 되돌아가야 할 수 있습니다.

Gitaly Cluster를 다운그레이드하는 경우(다중 Praefect 노드인 경우):

  1. 모든 Praefect 노드에서 Praefect 서비스를 중지합니다:

    gitlab-ctl stop praefect
    
  2. 하나의 Praefect 노드에서 이전 버전의 GitLab 패키지로 다운그레이드합니다.
  3. 다운그레이드된 노드에서 Praefect 마이그레이션 상태를 확인합니다:

    /opt/gitlab/embedded/bin/praefect -config /var/opt/gitlab/praefect/config.toml sql-migrate-status
    
  4. APPLIED 열에 unknown migration가 포함된 마이그레이션 수를 세어봅니다.
  5. 다운그레이드된 노드가 아닌 Praefect 노드에서 되돌릴 마이그레이션을 유효성을 검사하기 위해 롤백의 시험을 실행합니다. <CT_UNKNOWN> 보고된 알 수 없는 마이그레이션이 다운그레이드된 노드에서 보고된 수입니다.

    /opt/gitlab/embedded/bin/praefect -config /var/opt/gitlab/praefect/config.toml sql-migrate <CT_UNKNOWN>
    
  6. 결과가 올바르게 보인다면 동일한 명령을 -f 옵션과 함께 실행하여 마이그레이션을 되돌립니다:

    /opt/gitlab/embedded/bin/praefect -config /var/opt/gitlab/praefect/config.toml sql-migrate -f <CT_UNKNOWN>
    
  7. 남은 Praefect 노드에서 GitLab 패키지를 다운그레이드하고 Praefect 서비스를 다시 시작합니다:

    gitlab-ctl start praefect
    

Gitaly Cluster로 마이그레이션

caution
Gitaly Cluster에는 일부 알려진 문제가 있습니다. 계속하기 전에 다음 정보를 검토하세요.

Gitaly Cluster로 마이그레이션하기 전에:

  • Gitaly Cluster 배포 전을 검토하세요.
  • 개선 사항 및 버그 수정을 활용하기 위해 가능한 최신 GitLab 버전으로 업그레이드하세요.

Gitaly Cluster로 마이그레이션하기 위해:

  1. 필요한 리포지터리를 만들어주세요. 리포지터리 스토리지 권장사항을 참조하세요.
  2. Gitaly Cluster를 생성하고 구성하세요.
  3. 기존 Gitaly 인스턴스가 아직 그렇게 구성되어 있지 않은 경우 기존 GitLab 인스턴스를 위해 TCP 사용로 구성하세요.
  4. 리포지터리를 이동하세요. Gitaly Cluster로 마이그레이션하려면 Gitaly Cluster 외부에서 저장된 기존 리포지터리를 이동해야 합니다. 자동 마이그레이션이 없지만 GitLab API를 사용하여 예정된 이동이 가능합니다.

default 리포지터리를 사용하지 않더라도 구성되어 있는지 확인해야 합니다. 이 한계에 대해 더 읽기.

Gitaly 클러스터에서 이주하기

Gitaly 클러스터의 제한 사항과 절충안이 환경에 적합하지 않다고 판단되면, sharded Gitaly 인스턴스로 이주할 수 있습니다:

  1. 새로운 Gitaly 서버를 생성하고 구성합니다.
  2. 리포지터리를 이동하여 새롭게 생성된 리포지터리로 이동합니다. 이를 shard 또는 그룹별로 이동할 수 있으며, 이를 통해 여러 Gitaly 서버에 분산시킬 수 있습니다.

Gitaly 클러스터로 전환하기

복잡성을 제거하기 위해 GitLab에서 직접 Git 액세스를 제거해야합니다. 그러나 일부 GitLab 설치에서는 여전히 NFS에 Git 리포지터리가 필요합니다.

GitLab에서 직접 Git 액세스를 제거하기 위한 노력의 두 가지 측면은 다음과 같습니다:

  • GitLab에서 수행하는 비효율적인 Gitaly 쿼리의 수를 줄입니다.
  • 결함 허용 및 수평 확장 가능한 GitLab 인스턴스의 관리자들에게 NFS를 이주하도록 설득합니다.

두 번째 측면이 유일한 실질적인 해결책을 제시합니다. 이를 위해 Gitaly 클러스터를 개발했습니다.