Gitaly 및 Gitaly 클러스터
Gitaly은 Git 리포지터리에 대한 고수준의 RPC 액세스를 제공합니다. GitLab에서는 Git 데이터의 읽기 및 쓰기에 사용됩니다.
Gitaly는 모든 GitLab 설치에 존재하며 Git 리포지터리의 저장 및 검색을 조정합니다. Gitaly는 다음과 같을 수 있습니다:
- 단일 인스턴스 Linux 패키지 설치(하나의 머신에 모든 GitLab)에서 작동하는 백그라운드 서비스
- 스케일링 및 가용성 요구에 따라 전체 클러스터 구성에서 자체 인스턴스로 분리되고 구성될 수 있습니다.
Gitaly는 클라이언트-서버 아키텍처를 구현합니다:
- Gitaly 서버는 Gitaly 자체를 실행하는 모든 노드입니다.
- Gitaly 클라이언트는 Gitaly 서버에 요청을 하는 프로세스를 실행하는 모든 노드입니다. Gitaly 클라이언트는 _Gitaly consumers_로도 알려져 있으며 다음을 포함합니다:
Gitaly는 GitLab의 Git 리포지터리 액세스만 관리합니다. 다른 유형의 GitLab 데이터는 Gitaly를 통해 액세스되지 않습니다.
GitLab은 구성된 리포지터리 스토리지를 통해 리포지터리에 액세스합니다. 각 새 리포지터리는 구성된 가중치에 따라 리포지터리 스토리지 중 하나에 저장됩니다. 각 리포지터리 스토리지는 다음 중 하나일 수 있습니다:
- 저장 경로를 사용하여 리포지터리에 직접 액세스하는 Gitaly 리포지터리로, 각 리포지터리가 단일 Gitaly 노드에 저장됩니다. 모든 요청은이 노드로 라우팅됩니다.
-
Gitaly 클러스터에서 제공되는 가상 리포지터리로, 각 리포지터리를 여러 Gitaly 노드에 저장할 수 있어 오류 허용성이 있습니다. Gitaly 클러스터에서는:
- 읽기 요청은 여러 Gitaly 노드 사이에서 분산되어 성능을 향상시킬 수 있습니다.
- 쓰기 요청은 리포지터리 복제본에 브로드캐스트됩니다.
Gitaly 클러스터를 배포하기 전에
Gitaly 클러스터는 오류 허용성의 이점을 제공하지만 추가적인 설정 및 관리 복잡성이 있습니다. Gitaly 클러스터를 배포하기 전에 다음을 검토하세요:
- 기존 알려진 문제.
- 스냅샷 제한.
- 구성 안내 및 리포지터리 저장 옵션을 확인하여 Gitaly 클러스터가 가장 적합한 설정인지 확인합니다.
아직 Gitaly 클러스터로 마이그레이션하지 않은 경우 두 가지 옵션이 있습니다:
- 조각난 Gitaly 인스턴스.
- Gitaly 클러스터.
질문이 있으시면 고객 성공 관리자 또는 고객 지원팀에 문의하세요.
알려진 문제
다음 표는 Gitaly 클러스터 사용에 영향을주는 현재 알려진 문제를 개요로 보여줍니다. 이러한 문제의 현재 상태에 대해서는 참조 문제 및 에픽을 참조하세요.
문제 | 요약 | 피하는 방법 |
---|---|---|
Gitaly 클러스터 + Geo - 실패한 동기화를 다시 시도하는 문제 | Geo 보조 사이트에서 Gitaly 클러스터를 사용하는 경우 동기화에 실패한 리포지터리는 Geo가 다시 동기화 할 때 계속 실패할 수 있습니다. 이 상태에서 회복하려면 매뉴얼 단계를 실행하기 위해 지원팀의 지원이 필요합니다. | GitLab 15.0 이전에 알려진 해결책이 없습니다. 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(Solid-State Drive)를 사용하는 것을 강력히 권장합니다.
이 SSD는 다음과 같은 처리량이 있어야 합니다:
- 읽기 작업에 대해 초당 8,000 개의 입출력 작업(IOPS)
- 쓰기 작업에 대해 초당 2,000 개의 IOPS
이러한 IOPS 값은 초기 권장 사항으로, 환경의 작업량 규모에 따라 더 크거나 작은 값으로 조정될 수 있습니다. 환경을 클라우드 제공 업체에서 실행 중이라면 올바른 IOPS를 구성하는 방법에 대해서는 해당 업체의 문서를 참조하십시오.
리포지터리 데이터의 경우 Gitaly 및 Gitaly 클러스터에서는 성능 및 일관성을 이유로 로컬 저장 공간만 지원됩니다. NFS나 클라우드 기반 파일 시스템과 같은 대체 방법은 지원되지 않습니다.
리포지터리 직접 액세스
GitLab은 Gitaly 리포지터리에 직접적으로 Git 클라이언트나 다른 도구로 접근하는 것을 권장하지 않습니다. 왜냐하면 Gitaly는 지속적으로 개선 및 변경되기 때문에 이러한 개선 사항은 여러분의 가정을 무효화시켜 성능 저하, 불안정성, 심지어 데이터 손실을 유발할 수 있습니다. 예를 들어:
- Gitaly에는
info/refs
광고 캐시와 같은 최적화가 있으며 이는 공식 gRPC 인터페이스를 사용하여 리포지터리에 대한 액세스를 제어하고 모니터링하는 것에 의존합니다. - Gitaly 클러스터에는 분산된 읽기와 같은 최적화가 있으며 이는 gRPC 인터페이스 및 데이터베이스에 의존하여 리포지터리 상태를 결정합니다.
Gitaly
다음은 직접적인 Gitaly 액세스를 사용하도록 설정된 GitLab을 보여줍니다:
이 예시에서:
- 각 리포지터리는
storage-1
,storage-2
, 또는storage-3
중 하나에 저장됩니다. - 각 리포지터리는 Gitaly 노드에 의해 서비스됩니다.
- 세 Gitaly 노드는 각자의 파일 시스템에 데이터를 저장합니다.
Gitaly 아키텍처
다음은 Gitaly 클라이언트-서버 아키텍처를 설명합니다:
Gitaly 구성
Gitaly는 Linux 패키지 설치 시 사전 구성되어 있으며, 최대 1000 사용자에게 적합한 설정입니다. 다음을 위해:
- 최대 2000 사용자용 Linux 패키지 설치의 경우, 구체적인 Gitaly 구성 지침을 참조하십시오.
- 자체 컴파일된 설치 또는 사용자 정의 Gitaly 설치의 경우, Gitaly 구성을 참조하십시오.
매일 Git 쓰기 작업을 수행하는 2000명 이상의 활성 사용자를 위한 GitLab 설치는 Gitaly 클러스터를 사용하는 것이 가장 적합할 수 있습니다.
Gitaly CLI
gitaly
명령은 Gitaly 관리자를 위한 추가 하위 명령어를 제공하는 명령줄 인터페이스입니다. 예를 들어, Gitaly CLI는 다음을 위해 사용됩니다:
- 리포지터리에 대한 사용자 정의 Git 후크 구성.
- Gitaly 구성 파일 유효성 검사.
- 내부 Gitaly API의 접근성 확인.
다른 하위 명령에 대한 자세한 정보는 gitaly --help
를 실행하십시오.
리포지터리 백업
GitLab 외의 도구를 사용하여 리포지터리를 백업하거나 동기화하는 경우, 리포지터리 데이터를 복사하는 동안 쓰기 작업을 방지해야 합니다.
Gitaly 클러스터
Git 리포지터리는 GitLab의 Gitaly 서비스를 통해 제공되며, GitLab의 작동에 중요합니다. 사용자, 리포지터리 및 활동이 증가할수록 Gitaly를 적절히 확장하는 것이 중요합니다.
- 리소스 고갈로 인해 Git, Gitaly 및 GitLab 응용 프로그램 성능이 저하되기 전에 Git에 사용 가능한 CPU 및 메모리 리소스를 증가시키십시오.
- 쓰기 작업이 실패하는 저장 공간 한계에 도달하기 전에 사용 가능한 저장 공간을 증가시키십시오.
- 시스템의 단일 장애점을 제거하여 오류 허용성을 향상시키십시오. 서비스의 저하로 인해 프로덕션 환경에 변경 사항을 배포하지 못하는 경우 Git을 미션 크리티컬 서비스로 고려해야 합니다.
Gitaly는 클러스터 구성에서 다음을 수행하여 오류 허용성을 향상시킬 수 있습니다:
- Gitaly 서비스의 확장.
- 오류 허용성 증가.
이 구성에서 모든 Git 리포지터리는 클러스터 내 여러 Gitaly 노드에 저장될 수 있습니다.
Gitaly 클러스터를 사용하면 다음과 같이 오류 허용성을 향상시킬 수 있습니다:
- 웜 스탠바이 Gitaly 노드에 쓰기 작업을 복제합니다.
- Gitaly 노드 장애를 감지합니다.
- Git 요청을 자동으로 사용 가능한 Gitaly 노드로 라우팅합니다.
다음은 storage-1
에 액세스하기 위해 설정된 GitLab을 보여줍니다. 이 storage-1
은 Gitaly 클러스터에서 제공되는 가상 리포지터리입니다:
이 예시에서:
- 리포지터리는
storage-1
이라는 가상 리포지터리에 저장됩니다. - 세 Gitaly 노드인
gitaly-1
,gitaly-2
,gitaly-3
가storage-1
액세스를 제공합니다. - 이 세 Gitaly 노드는 각자 별도의 해시화된 저장 위치에 데이터를 저장합니다.
-
복제 요소는
3
입니다. 각 리포지터리에 대해 세 개의 사본이 유지됩니다.
단일 노드 장애를 가정한 Gitaly 클러스터의 가용성 목표는 다음과 같습니다:
-
복구 지점 목표(RPO): 1분 미만.
쓰기 작업이 비동기적으로 복제됩니다. 새로 승격된 프라이머리에 복제되지 않은 모든 쓰기 작업은 손실됩니다.
강력한 일관성은 일부 상황에서 손실을 방지합니다.
-
복구 시간 목표(RTO): 10초 미만. 각 Praefect 노드에서 1초마다 실행되는 상태 확인에 의해 장애가 감지됩니다. 장애 복구에는 각 Praefect 노드에서 10회 연속된 상태 확인 실패가 필요합니다.
RPO 및 RTO의 개선 사항은 에픽 8903에서 제안되어 있습니다.
Geo와 비교
Gitaly 클러스터와 Geo는 모두 여분성을 제공합니다. 그러나 여분성의:
- Gitaly 클러스터는 데이터 저장에 대한 결함 허용성을 제공하며 사용자에게는 보이지 않습니다. 사용자가 Gitaly 클러스터를 사용하는지 알 수 없습니다.
- Geo는 GitLab 인스턴스 전체에 대한 복제 및 재해 복구 기능을 제공합니다. 사용자는 복제를 사용하는지 알 수 있습니다. Geo는 여러 데이터 유형을 복제합니다 (Git 데이터 포함).
다음 표는 Gitaly 클러스터와 Geo 간의 주요 차이점을 보여줍니다:
도구 | 노드 | 위치 | 지연 허용 여부 | 장애 조치 | 일관성 | 여분성 제공 대상 |
---|---|---|---|---|---|---|
Gitaly 클러스터 | 다중 | 단일 | 1초 미만, 이상적으로는 몇 자리 밀리초 | 자동 | 강력 | Git의 데이터 저장 |
Geo | 다중 | 다중 | 최대 1분 | 매뉴얼 | 최종 일관적 | 전체 GitLab 인스턴스 |
자세한 정보는 다음을 참조하십시오:
가상 리포지터리
가상 리포지터리를 사용하면 GitLab의 단일 리포지터리 스토리지를 간소화하여 관리할 수 있습니다.
Gitaly 클러스터의 가상 리포지터리는 일반적으로 직접 Gitaly 리포지터리 구성을 대체할 수 있습니다. 그러나 이는 각 리포지터리를 여러 Gitaly 노드에 저장하는 데 필요한 추가 저장 공간을 희생함으로써 달성됩니다. 직접 Gitaly 리포지터리 대신 Gitaly 클러스터 가상 리포지터리를 사용하는 이점은:
- 각 Gitaly 노드가 모든 리포지터리의 사본을 가지고 있기 때문에 향상된 장애 허용성.
- 읽기 부하가 Gitaly 노드에 분산되므로 과도한 프로비저닝이 필요 없어지므로 리소스 활용도가 향상됩니다.
- 읽기 부하가 Gitaly 노드에 균등하게 분산되기 때문에 성능을 위해 매뉴얼으로 리밸런싱할 필요가 없습니다.
- 모든 Gitaly 노드가 동일하기 때문에 관리가 간단합니다.
리플리케이션 요소를 사용하여 리포지터리 사본의 수를 구성할 수 있습니다. 모든 리포지터리에 대해 동일한 리플리케이션 요소를 가지는 것은 비경제적일 수 있습니다. 매우 큰 GitLab 인스턴스에 대해 더 큰 유연성을 제공하기 위해 변수 리플리케이션 요소가 이 이슈에서 추적됩니다.
표준 Gitaly 리포지터리와 마찬가지로 가상 리포지터리도 분할될 수 있습니다.
리포지터리 레이아웃
Gitaly 클러스터의 가상 리포지터리는 단일 리포지터리처럼 보이지만 실제로 여러 물리적 리포지터리로 구성됩니다. Gitaly 클러스터는 각 물리적 리포지터리에 대한 각 작업을 복제해야 합니다. 작업은 일부 물리적 리포지터리에서 성공할 수 있지만 다른 리포지터리에서 실패할 수 있습니다.
부분적으로 적용된 작업은 다른 작업에 문제를 일으킬 수 있으며 시스템을 회복할 수 없는 상태로 남길 수 있습니다. 이러한 종류의 문제를 피하려면 각 작업은 완전히 적용되거나 전혀 적용되지 않아야 합니다. 이러한 작업의 특성을 원자성
(https://en.wikipedia.org/wiki/Atomicity_(database_systems))이라고 합니다.
GitLab은 리포지터리 스토리지에서의 리포지터리 레이아웃을 제어합니다. GitLab은 리포지터리 스토리지에게 리포지터리를 어디에 생성, 삭제 및 이동할지 지시합니다. 이러한 작업은 여러 물리적 리포지터리에 적용될 때 원자성 문제를 일으킬 수 있습니다. 예를 들어:
- GitLab이 한 개의 복제본이 사용 불가능한 상태에서 리포지터리를 삭제합니다.
- 나중에 GitLab이 리포지터리를 다시 만듭니다.
이 결과로 사용 불가능한 이전 복제본은 충돌을 일으킬 수 있으며 리포지터리의 재생성을 방해할 수 있습니다.
이러한 원자성 문제는 지난 시간 동안 여러 문제를 유발했습니다:
- Gitaly 클러스터와 함께 보조 사이트로 Geo 동기화.
- 백업 복원.
- 리포지터리 스토리지 간의 리포지터리 이동.
Gitaly 클러스터는 이러한 작업에 대한 원자성을 제공하여 부분적으로 적용된 작업으로 인한 충돌을 방지합니다.
클라이언트 생성 복제 경로
리포지터리는 Gitaly 클라이언트에 의해 상대 경로에서 리포지터리에 저장됩니다. 이러한 경로는 @cluster
접두사로 시작하지 않아서 식별할 수 있습니다. 상대 경로는 해시 리포지터리 스키마를 따릅니다.
Praefect가 생성한 복제 경로 (GitLab 15.0 이상)
Gitaly 클러스터가 리포지터리를 생성하면 리포지터리에 _리포지터리 ID_라는 고유하고 영구적인 ID를 할당합니다. 리포지터리 ID는 Gitaly 클러스터 내부적이며 GitLab의 다른 곳의 ID와 관련이 없습니다. 만약 리포지터리가 Gitaly 클러스터에서 제거되고 나중에 다시 이동되면 리포지터리는 새로운 리포지터리 ID가 할당되며 Gitaly 클러스터의 관점에서는 다른 리포지터리입니다. 리포지터리 ID의 순서는 항상 증가하지만 일련에는 갭이 있을 수 있습니다.
리포지터리 ID는 클러스터 내의 각 리포지터리에 대해 리포지터리의 고유한 리포지터리 경로인 _복제 경로_를 파생하는 데 사용됩니다. 리포지터리의 복제본은 모두 리포지터리에 있는 동일한 복제 경로에 저장됩니다. 복제 경로는 _상대 경로_와 구별됩니다:
- 상대 경로는 Gitaly 클라이언트가 고유하게 식별하는 리포지터리와 함께 사용되는 이름입니다.
- 복제 경로는 실제 물리적 리포지터리에서의 실제 경로입니다.
Praefect는 클라이언트 요청을 처리할 때 클라이언트의 (가상 리포지터리, 상대 경로)
식별자를 물리적 리포지터리 (리포지터리, 복제 경로)
식별자로 변환합니다.
다음과 같은 형식의 복제 경로:
- Object pools의 경우
@cluster/pools/<xx>/<xx>/<리포지터리 ID>
입니다. Object pools은 다른 디렉터리에 저장됩니다. Gitaly가 이를 가지고 있어야만 가지고는 파일을 기준으로해서 불필요하게 이들을 가지고 이리가능하다. 정보가 있는 버리려 해더라도 객체 풀을 가지가 더유한인 가능성이 있다. - 기타 리포지터리의 경우
@클러스터/리포지터리/<xx>/<xx>/<리포지터리 ID>
입니다.
예를 들어, @클러스터/리포지터리/6f/96/54771
입니다.
복제 경로의 마지막 컴포넌트인 54771
은 리포지터리 ID입니다. 이를 사용하여 디스크상에서 리포지터리를 식별할 수 있습니다.
<xx>/<xx>
는 리포지터리 ID의 문자열 표현의 SHA256 해시의 처음 네 자릿수입니다. 이들 자릿수는 문제가 발생할 수 있는 지나치게 큰 디렉터리를 피하기 위해 리포지터리를 균등하게 분산하기 위해 사용됩니다. 이 경우 54771
는 6f960ab01689464e768366d3315b3d3b2c28f38761a58a70110554eb04d582f7
로 해시가 되므로 처음 네 자릿수는 6f
입니다.
디스크 상의 리포지터리 식별
praefect metadata
하위 명령을 사용하여:
- 메타데이터 리포지터리에서 리포지터리의 가상 리포지터리 및 상대 경로를 검색합니다. 해시된 리포지터리 경로를 획득한 후 Rails 콘솔을 사용하여 프로젝트 경로를 검색할 수 있습니다.
- 리포지터리가 클러스터 내 어디에 저장되어 있는지 다음 중 하나로 확인합니다:
- 가상 리포지터리 및 상대 경로.
- 리포지터리 ID.
디스크 상의 리포지터리에는 Git 구성 파일에서 프로젝트 경로도 포함되어 있습니다. 메타데이터가 삭제된 경우에도 구성 파일을 사용하여 프로젝트 경로를 결정할 수 있습니다. 해시된 리포지터리 경로에서 프로젝트 이름으로의 지침에 따릅니다.
작업의 원자성
Gitaly Cluster는 리포지터리 생성, 삭제 및 이동 작업의 원자성을 보장하기 위해 PostgreSQL 메타데이터 리포지터리와 리포지터리 레이아웃을 사용합니다. 디스크 작업은 여러 리포지터리에 걸쳐 원자적으로 적용될 수 없습니다. 그러나 PostgreSQL은 메타데이터 작업의 원자성을 보장합니다. Gitaly Cluster는 작업을 모델링하여 실패한 작업이 항상 메타데이터를 일관되게 남기도록 합니다. 디스크에는 성공한 작업 이후에도 불필요하게 디스크 공간을 차지할 수 있는 낡은 상태가 포함될 수 있습니다. 이러한 상황은 예상 가능하며 나중에 정리 작업을 수행할 때까지 향후 작업에 방해가 될 뿐입니다.
남은 리포지터리를 정리하는 백그라운드 크롤러에 대한 작업이 진행 중입니다.
리포지터리 생성
리포지터리를 생성할 때 Praefect는 다음을 수행합니다:
- PostgreSQL에서 리포지터리 ID를 예약하며, 이는 원자적이므로 생성은 동일한 ID를 받지 않습니다.
- 리포지터리가 성공적으로 만들어지면 Gitaly 리포지터리에 복제본을 생성하며, 이는 리포지터리 ID에서 파생된 복제 경로에 따라 수행됩니다.
- 리포지터리가 디스크에 성공적으로 만들어진 후, 메타데이터 레코드를 생성합니다.
심지어 두 개의 동시 작업이 동일한 리포지터리를 만들어도, 다른 디렉터리에 저장되어 충돌하지 않습니다. 완료된 작업으로 인해 첫 번째로 완료된 작업이 메타데이터 레코드를 만들고 다른 작업은 “이미 존재함” 오류로 실패합니다. 실패한 생성으로 인해 남은 리포지터리가 리포지터리에 남을 수 있습니다. 남은 리포지터리를 정리하는 백그라운드 크롤러에 대한 작업이 진행 중입니다.
리포지터리 ID는 PostgreSQL의 repositories_repository_id_seq
에서 생성됩니다. 위의 예제에서, 실패한 작업은 리포지터리 ID를 하나 가져가고 이를 사용하여 리포지터리를 성공적으로 만들지 못했습니다. 실패한 리포지터리 생성으로 인해 리포지터리 ID에 갭이 발생할 것으로 예상됩니다.
리포지터리 삭제
리포지터리는 해당 메타데이터 레코드를 제거함으로써 삭제됩니다. 메타데이터 레코드가 삭제되는 즉시 리포지터리는 논리적으로 존재하지 않게 됩니다. PostgreSQL은 제거 작업의 원자성을 보장하며, 동시 삭제는 “찾을 수 없음” 오류로 실패합니다. 메타데이터 레코드를 성공적으로 삭제한 후, Praefect는 리포지터리에서 복제본을 제거하려고 시도합니다. 이 과정에서 실패할 수 있으며, 리포지터리에 남은 상태가 발생합니다. 남은 상태는 최종적으로 정리됩니다.
리포지터리 이동
Gitaly와 달리, Gitaly Cluster는 리포지터리를 리포지터리에서 이동하는 것이 아니라 메타데이터 리포지터리에서 리포지터리의 상대 경로를 업데이트하여 가상으로 이동합니다.
컴포넌트
Gitaly Cluster는 여러 컴포넌트로 구성됩니다:
- 요청을 분배하고 오류 허용적인 Praefect 노드에 대한 요청을 라우팅하는 부하 분산기.
- 클러스터를 관리하고 Gitaly 노드로의 요청을 라우팅하기 위한 Praefect 노드.
- 클러스터 메타데이터를 영구적으로 저장하기 위한 PostgreSQL 데이터베이스 및 Praefect의 데이터베이스 연결을 풀링하기 위해 권장되는 PgBouncer.
- 리포지터리 저장 및 Git 액세스를 제공하기 위한 Gitaly 노드.
아키텍처
Praefect는 Gitaly의 라우터 및 트랜잭션 관리자이자 Gitaly Cluster를 실행하기 위한 필수적인 컴포넌트입니다.
추가 정보는 Gitaly 고가용성(HA) 설계를 참조하십시오.
기능
Gitaly Cluster는 다음 기능을 제공합니다:
- Gitaly 노드 간의 분산 읽기.
- 보조 복제본의 강력한 일관성.
- 증가된 중복성을 위한 리포지터리의 복제 요소.
- 주 Gitaly 노드에서 보조 Gitaly 노드로 자동 장애 조치.
- 복제 대기열에서 데이터 손실을 확인하는 보고.
가로로 읽기를 분배를 포함한 개선을 위한 Gitaly Cluster epic을 참조하십시오.
분산 읽기
Gitaly Cluster는 가상 리포지터리로 구성된 Gitaly 노드 사이의 읽기 작업을 분산 지원합니다.
‘ACCESSOR’ 옵션으로 표시된 모든 RPC는 최신 상태가 유지되고 건강한 Gitaly 노드로 리디렉션됩니다. 예를 들어 GetBlob
.
이 맥락에서의 ‘최신 상태’는 다음을 의미합니다:
- 해당 Gitaly 노드에 대해 복제 작업이 예약되어 있지 않습니다.
- 마지막 복제 작업이 ‘완료’ 상태인 경우.
최신 상태가 유지되지 않는 노드가 없는 경우에는 주 노드가 요청을 처리하게 됩니다:
- 최신 상태가 유지되지 않는 노드가 없는 경우.
- 노드 선택 중 오류가 발생한 경우.
대용량이고 많이 수정된 리포지터리(예: 멀티 기가바이트 모노 리포지터리)를 보유하고 있다면, 변경 사항이 두 번째 서버로 복제되는 것보다 빠르게 발생하는 경우, 주 노드는 대부분 또는 모든 요청을 처리할 수 있습니다. 이러한 경우에는 CI/CD 작업 및 기타 리포지터리 트래픽이 주 노드의 용량에 의해 병목 현상을 겪을 수 있습니다.
Prometheus를 사용하여 읽기 분산 엿보기가 가능합니다.
강력한 일관성
- GitLab 14.0에서 강력한 일관성이 주요 복제 방법입니다.
Gitaly Cluster는 변경 사항을 모든 건강하고 최신 상태의 복제본에 동기적으로 쓰는 것으로써 강력한 일관성을 제공합니다. 트랜잭션 시점에 복제본이 오래된 상태이거나 건강하지 않은 경우에는 쓰기가 비동기적으로 복제됩니다.
강력한 일관성이 주요 복제 방법입니다. 일부 작업은 강력한 일관성 대신 복제 작업(최종 일관성)을 사용합니다. 자세한 내용은 강력한 일관성 이픽을 참조하십시오.
강력한 일관성을 사용할 수 없는 경우, Gitaly Cluster는 최종 일관성 대신 보장됩니다. 이 경우 Gitaly Cluster는 주 노드에 쓰여진 후에 모든 작성을 보조 Gitaly 노드로 복제합니다.
강력한 일관성의 모니터링에 대한 자세한 내용은 Gitaly Cluster의 Prometheus 메트릭 문서를 참조하십시오.
복제 요소
복제 요소는 주어진 리포지터리의 Gitaly Cluster가 유지 관리하는 복사본의 수입니다. 더 높은 복제 요소는 다음과 같은 이점을 제공합니다:
- 더 나은 중복 및 읽기 워크로드 분산
- 더 높은 리포지터리 비용
기본 설정에서 Gitaly Cluster는 모든 리포지터리를 virtual storage 에 복제합니다.
구성 정보는 복제 요소 구성를 참조하세요.
Gitaly Cluster 구성
Gitaly Cluster 구성에 대한 자세한 정보는 Gitaly Cluster 구성을 참조하세요.
Gitaly Cluster 업그레이드
Gitaly Cluster를 업그레이드하려면 제로 다운타임 업그레이드 문서를 참조하세요.
Gitaly Cluster를 이전 버전으로 다운그레이드
Gitaly Cluster를 이전 버전으로 롤백해야 하는 경우, 일부 Praefect 데이터베이스 마이그레이션이 되돌아가야 할 수 있습니다.
다음과 같이 Gitaly Cluster를 다운그레이드합니다(여러 Praefect 노드를 사용하는 경우):
-
모든 Praefect 노드에서 Praefect 서비스를 중지합니다:
gitlab-ctl stop praefect
- Praefect 노드 중 하나에서 이전 버전의 GitLab 패키지로 다운그레이드합니다.
-
다운그레이드된 노드에서 Praefect 마이그레이션 상태를 확인합니다:
/opt/gitlab/embedded/bin/praefect -config /var/opt/gitlab/praefect/config.toml sql-migrate-status
-
APPLIED
열에서unknown migration
을 가진 마이그레이션 수를 세어봅니다. -
다운그레이드된 노드에서 보고된 알 수 없는 마이그레이션의 수를 확인하기 위해 롤백의 드라이 런을 실행합니다.
<CT_UNKNOWN>
여기서<CT_UNKNOWN>
은 다운그레이드된 노드에서 보고한 알 수 없는 마이그레이션의 수입니다./opt/gitlab/embedded/bin/praefect -config /var/opt/gitlab/praefect/config.toml sql-migrate <CT_UNKNOWN>
-
결과가 올바른 것으로 보인다면, 동일한 명령을
-f
옵션과 함께 실행하여 마이그레이션을 되돌립니다:/opt/gitlab/embedded/bin/praefect -config /var/opt/gitlab/praefect/config.toml sql-migrate -f <CT_UNKNOWN>
-
나머지 Praefect 노드에 GitLab 패키지를 다운그레이드하고 Praefect 서비스를 다시 시작합니다:
gitlab-ctl start praefect
Gitaly Cluster로 마이그레이션
Gitaly Cluster로 마이그레이션하기 전에 다음을 검토하세요:
- Gitaly Cluster를 배포하기 전에를 검토하세요.
- 개선 사항과 버그 수정의 이점을 누리기 위해 GitLab의 가능한 최신 버전으로 업그레이드하세요.
Gitaly Cluster로 마이그레이션하려면:
- 필요한 리포지터리를 생성하세요. 리포지터리 저장 권장 사항을 참조하세요.
- Gitaly Cluster를 만들고 구성하세요.
- 기존 Gitaly 인스턴스가 아직 해당 방식으로 구성되어 있지 않으면, 해당 인스턴스를 TCP 사용하도록 구성하세요.
- 리포지터리를 이동하세요. Gitaly Cluster로 마이그레이션하려면 Gitaly Cluster 외부에 저장된 기존 리포지터리를 이동해야 합니다. 자동 마이그레이션이 없지만 이동은 GitLab API로 예약할 수 있습니다.
default
리포지터리 스토리지를 사용하지 않더라도 해당 리포지터리가 구성되어 있는지 확인해야 합니다.
이 제한사항에 대해 자세히 읽으십시오.
Gitaly Cluster에서 이동하기
Gitaly Cluster의 제한 사항과 트레이드오프가 환경에 적합하지 않다고 판단되면 Gitaly Cluster에서 샤드된 Gitaly 인스턴스로 이동할 수 있습니다.
다음과 같이 Gitaly 서버를 만들고 구성하세요: 새 Gitaly 서버 구성.
새로운 리포지터리로 리포지터리를 이동하세요. 샤드별이나 그룹별로 이동할 수 있으며, 이로써 리포지터리를 여러 Gitaly 서버에 분산시킬 수 있습니다.
Gitaly Cluster로 전환하기
복잡성을 제거하려면 GitLab에서 직접적인 Git 액세스를 제거해야 합니다. 그러나 일부 GitLab 설치에서는 NFS에서 Git 리포지터리가 필요하기 때문에 지금 당장 제거할 수 없습니다.
GitLab에서 직접적인 Git 액세스를 제거하기 위한 노력에는 두 가지 측면이 있습니다:
- GitLab에서 수행하는 비효율적인 Gitaly 쿼리 수를 줄입니다.
- 고장 허용 또는 가로 확장된 GitLab 인스턴스의 관리자들에게 NFS에서 마이그레이션하도록 설득합니다.
두 번째 측면이 유일한 실질적인 해결책을 제시합니다. 이를 위해 Gitaly Cluster 을 개발했습니다.