Gitaly Cluster (Praefect)
GitLab v19.2- Offering: GitLab Self-Managed GitLab에서 Git 스토리지는 Gitaly 서비스를 통해 제공되며, GitLab 운영에 필수적입니다. 리소스 고갈로 인해 Git, Gitaly, GitLab 애플리케이션 성능이 저하되기 전에 Git에 사용 가능한 CPU와 메모리 리소스를 늘립니다.
-
Tier: Free, Premium, Ultimate
- Offering: GitLab Self-Managed
GitLab에서 Git 스토리지는 Gitaly 서비스를 통해 제공되며, GitLab 운영에 필수적입니다. 사용자, 리포지터리, 활동이 증가함에 따라 Gitaly를 적절히 확장하는 것이 중요합니다:
-
리소스 고갈로 인해 Git, Gitaly, GitLab 애플리케이션 성능이 저하되기 전에 Git에 사용 가능한 CPU와 메모리 리소스를 늘립니다.
-
스토리지 한도에 도달하여 쓰기 작업이 실패하기 전에 사용 가능한 스토리지를 늘립니다.
-
서비스 저하로 인해 프로덕션에 변경 사항을 배포할 수 없게 되는 경우 Git을 미션 크리티컬로 간주하여 단일 장애 지점을 제거하고 내결함성을 개선합니다.
Gitaly는 클러스터 구성으로 실행하여 다음을 달성할 수 있습니다:
-
Gitaly 서비스 확장.
-
내결함성 향상.
이 구성에서는 모든 Git 리포지터리를 클러스터의 여러 Gitaly 노드에 저장할 수 있습니다.
Gitaly Cluster (Praefect)를 사용하면 다음과 같은 방법으로 내결함성이 향상됩니다:
-
웜 스탠바이 Gitaly 노드에 쓰기 작업을 복제합니다.
-
Gitaly 노드 오류를 감지합니다.
-
사용 가능한 Gitaly 노드로 Git 요청을 자동으로 라우팅합니다.
Gitaly Cluster (Praefect)에 대한 기술 지원은 GitLab Premium 및 Ultimate 고객으로 제한됩니다.
다음은 Gitaly Cluster (Praefect)가 제공하는 가상 스토리지인
storage-1에 액세스하도록 설정된 GitLab을 보여줍니다:
[
](/19.2/administration/gitaly/praefect/img/cluster_example_v13_3.png)
이 예시에서:
-
리포지터리는
storage-1이라는 가상 스토리지에 저장됩니다. -
세 개의 Gitaly 노드가
storage-1액세스를 제공합니다:gitaly-1,gitaly-2,gitaly-3. -
세 개의 Gitaly 노드가 세 개의 별도 해시 스토리지 위치에 데이터를 공유합니다.
-
복제 인수는
3입니다. 각 리포지터리의 복사본 3개가 유지됩니다.
단일 노드 장애를 가정한 Gitaly Cluster (Praefect)의 가용성 목표는 다음과 같습니다:
복구 시점 목표(RPO): 1분 미만.
쓰기는 비동기적으로 복제됩니다. 새로 승격된 기본 노드로 복제되지 않은 쓰기는 손실됩니다. 장애가 발생한 노드에서 진행 중이던 읽기 작업은 종료됩니다.
강력한 일관성은 일부 상황에서 손실을 방지합니다.
복구 시간 목표(RTO): 10초 미만. 각 Praefect 노드가 매초 실행하는 상태 확인으로 중단을 감지합니다. 페일오버는 각 Praefect 노드에서 연속으로 10번의 상태 확인이 실패해야 합니다.
RPO 및 RTO 개선 사항은 에픽 8903에서 제안되고 있습니다.
전체 클러스터 장애가 발생하면 재해 복구 계획을 실행해야 합니다. 이는 앞서 설명한
RPO 및 RTO에 영향을 줄 수 있습니다.
Gitaly Cluster (Praefect) 배포 전#
Gitaly Cluster (Praefect)는 내결함성의 이점을 제공하지만, 추가적인 설정 및 관리 복잡성을 수반합니다. Gitaly Cluster (Praefect)를 배포하기 전에 다음을 참조하세요:
-
기존 알려진 문제.
-
구성 지침 및 리포지터리 스토리지 옵션을 통해 Gitaly Cluster (Praefect)가 귀하에게 적합한 설정인지 확인하세요.
아직 Gitaly Cluster (Praefect)로 마이그레이션하지 않은 경우 두 가지 옵션이 있습니다:
-
샤딩된 Gitaly 인스턴스.
-
Gitaly Cluster (Praefect).
질문이 있으시면 고객 성공 관리자 또는 고객 지원팀에 문의하세요.
이미 Gitaly Cluster (Praefect)를 사용 중이고 문제나 제한을 경험하고 있다면, 복원 또는 복구에 대한 즉각적인 도움을 위해 고객 지원팀에 연락하세요.
알려진 문제#
다음 표는 Gitaly Cluster (Praefect) 사용에 영향을 미치는 현재 알려진 문제를 설명합니다. 이러한 문제의 현재 상태는 참조된 이슈 및 에픽을 참조하세요.
| 문제 | 요약 | 방지 방법 |
|---|---|---|
| Gitaly Cluster (Praefect) + Geo - 실패한 동기화 재시도 문제 | Geo 보조 사이트에서 Gitaly Cluster (Praefect)를 사용하는 경우, 동기화에 실패한 리포지터리는 Geo가 재동기화를 시도할 때 계속 실패할 수 있습니다. 이 상태에서 복구하려면 지원팀의 도움을 받아 수동 단계를 실행해야 합니다. | GitLab 15.0~15.2에서는 Geo 기본 사이트에서 gitaly_praefect_generated_replica_paths 기능 플래그를 활성화합니다. GitLab 15.3에서는 기능 플래그가 기본적으로 활성화됩니다. |
| 업그레이드 후 마이그레이션이 적용되지 않아 Praefect가 데이터베이스에 데이터를 삽입할 수 없음 | 완료된 마이그레이션으로 데이터베이스가 최신 상태로 유지되지 않으면 Praefect 노드가 표준 작업을 수행할 수 없습니다. | Praefect 데이터베이스가 모든 마이그레이션이 완료된 상태로 실행 중인지 확인하세요. 예를 들어 다음 명령은 적용된 모든 마이그레이션 목록을 표시해야 합니다: sudo -u git -- /opt/gitlab/embedded/bin/praefect -config /var/opt/gitlab/praefect/config.toml sql-migrate-status. 지원팀이 업그레이드 계획을 검토할 수 있도록 업그레이드 지원을 요청하는 것을 고려하세요. |
| 실행 중인 클러스터에서 스냅샷으로부터 Gitaly Cluster (Praefect) 노드 복원 | Gitaly Cluster (Praefect)는 일관된 상태로 실행되므로, 뒤처진 단일 노드를 도입하면 클러스터가 해당 노드의 데이터를 다른 노드의 데이터와 조정할 수 없게 됩니다. | 백업 스냅샷에서 단일 Gitaly Cluster (Praefect) 노드를 복원하지 마세요. 백업에서 복원해야 하는 경우: 1. GitLab을 종료합니다. 2. 모든 Gitaly Cluster (Praefect) 노드를 동시에 스냅샷합니다. 3. Praefect 데이터베이스의 데이터베이스 덤프를 만듭니다. |
| Kubernetes, Amazon ECS 또는 유사 환경에서 실행 시 제한 사항 | Gitaly Cluster (Praefect)는 지원되지 않으며 Gitaly에는 알려진 제한 사항이 있습니다. 자세한 내용은 에픽 6127을 참조하세요. | 참조 아키텍처를 사용하세요. |
| Praefect가 쓰기를 기록하기 전에 PostReceiveHook이 호출됨 | 경쟁 조건으로 인해 쓰기가 모든 노드에 복제되기 전에 PostReceiveHook이 실행될 수 있습니다. CI/CD 파이프라인이 아직 쓰기를 받지 못한 복제본을 대상으로 할 때, 이 경쟁 조건으로 인해 파이프라인이 couldn't find remote ref refs/merge-requests/$iid/{head,merge} 오류와 함께 실패합니다. 자세한 내용은 이슈 5406을 참조하세요 | 전체 job을 다시 시도하거나 페치 소스 Stage만 다시 시도하세요. 자세한 내용은 job stages 재시도를 참조하세요. |
| HPA 자동 스케일링으로 인해 스토리지 이동이 자동으로 실패할 수 있음 | Sidekiq Pod와 함께 수평 Pod 오토스케일러(HPA)를 사용할 때 job 실행 중 Pod 스케일링으로 인해 리포지터리 스토리지 이동이 자동으로 실패할 수 있습니다. | 리포지터리 스토리지 이동을 수행하기 전에 minReplicas = maxReplicas를 설정하여 마이그레이션 중 스케일링을 방지하도록 HPA를 고정된 복제본으로 구성하세요. |
스냅샷 백업 및 복구#
Gitaly Cluster (Praefect)는 스냅샷 백업을 지원하지 않습니다. 스냅샷 백업은 Praefect 데이터베이스가 디스크 스토리지와 동기화되지 않는 문제를 일으킬 수 있습니다. 복원 중 Praefect가 Gitaly 디스크 정보의 복제 메타데이터를 재구성하는 방식 때문에 공식 백업 및 복원 Rake 태스크를 사용해야 합니다.
증분 백업 방법을 사용하면 Gitaly Cluster (Praefect) 백업 속도를 높일 수 있습니다.
두 방법 중 어느 것도 사용할 수 없는 경우, 복원 도움을 위해 고객 지원팀에 문의하세요.
Geo와의 비교#
Gitaly Cluster (Praefect)와 Geo는 서로 다른 유형의 이중화를 제공합니다.
-
Gitaly Cluster (Praefect)의 이중화는 데이터 스토리지에 대한 내결함성을 제공하며 사용자에게는 보이지 않습니다.
-
Geo의 이중화는 GitLab 전체 인스턴스에 대한 복제(사용자에게 표시됨) 및 재해 복구를 제공합니다. Geo는 Git 데이터를 포함한 여러 데이터 유형을 복제합니다.
다음 표는 Gitaly Cluster (Praefect)와 Geo의 주요 차이점을 설명합니다:
| 도구 | 노드 | 위치 | 지연 허용 | 페일오버 | 일관성 | 이중화 제공 대상 |
|---|---|---|---|---|---|---|
| Gitaly Cluster (Praefect) | 여러 개 | 단일 | 1초 미만, 이상적으로는 한 자릿수 밀리초 | 자동 | 강력함 | Git의 데이터 스토리지 |
| Geo | 여러 개 | 여러 개 | 최대 1분 | 수동 | 최종적 | 전체 GitLab 인스턴스 |
자세한 내용은 다음을 참조하세요:
가상 스토리지#
가상 스토리지를 사용하면 GitLab에서 단일 리포지터리 스토리지를 사용하여 리포지터리 관리를 단순화할 수 있습니다.
Gitaly Cluster (Praefect)의 가상 스토리지는 일반적으로 직접 Gitaly 스토리지 구성을 대체할 수 있습니다. 단, 이는 각 리포지터리를 여러 Gitaly 노드에 저장하는 데 필요한 추가 스토리지 공간을 감수해야 합니다. 직접 Gitaly 스토리지 대신 Gitaly Cluster (Praefect) 가상 스토리지를 사용하는 이점은 다음과 같습니다:
-
각 Gitaly 노드에 모든 리포지터리의 복사본이 있으므로 내결함성이 향상됩니다.
-
읽기 부하가 Gitaly 노드 전체에 분산되므로 샤드별 최대 부하에 대한 과잉 프로비저닝 필요성이 줄어들어 리소스 활용도가 향상됩니다.
-
읽기 부하가 Gitaly 노드 전체에 분산되므로 성능을 위한 수동 재균형이 필요하지 않습니다.
-
모든 Gitaly 노드가 동일하므로 관리가 단순화됩니다.
리포지터리 복제본 수는 복제 인수를 사용하여 구성할 수 있습니다.
모든 리포지터리에 동일한 복제 인수를 적용하는 것은 비경제적일 수 있습니다. 매우 큰 GitLab 인스턴스에 더 큰 유연성을 제공하기 위해 가변 복제 인수가 이 이슈에서 추적되고 있습니다.
표준 Gitaly 스토리지와 마찬가지로 가상 스토리지도 샤딩될 수 있습니다.
다중 가상 스토리지#
Gitaly Cluster (Praefect) 배포에서 여러 가상 스토리지를 구성할 수 있습니다. 이를 통해 다음을 수행할 수 있습니다:
-
다양한 성능 특성을 가진 별도의 클러스터로 리포지터리를 구성합니다.
-
다양한 리포지터리 그룹에 서로 다른 복제 인수를 적용합니다.
-
인프라의 다양한 부분을 독립적으로 확장합니다.
가상 스토리지는 GitLab 서버의 gitlab_rails['repositories_storages']에 구성됩니다. 이
해시의 각 항목은 별개의 가상 스토리지를 나타냅니다. Praefect 구성은 어떤 Gitaly 노드가 각
가상 스토리지를 처리하는지 정의합니다. 서로 다른 가상 스토리지의 리포지터리는 완전히 독립적이며
가상 스토리지 간에 복제되지 않습니다.
예를 들어 다음과 같이 구성할 수 있습니다:
-
storage-1: 복제 인수가 3인 중요한 프로덕션 리포지터리를 위한 가상 스토리지. -
storage-2: 복제 인수가 2인 덜 중요한 리포지터리를 위한 가상 스토리지.
각 가상 스토리지에는 자체 Gitaly 노드 세트가 필요합니다.
%%{init: { "fontFamily": "GitLab Sans" }}%% graph TD accTitle: Multiple virtual storages accDescr: Example of multiple virtual storages, one with a replication factor of three and one with a replication factor of two.
GitLab[[GitLab server]]
Storage1[(storage-1<br/>Praefect cluster)]
Storage2[(storage-2<br/>Praefect cluster)]
GitLab --> Storage1
GitLab --> Storage2
Storage1 --> G1[Gitaly node 1]
Storage1 --> G2[Gitaly node 2]
Storage1 --> G3[Gitaly node 3]
Storage2 --> G4[Gitaly node 4]
Storage2 --> G5[Gitaly node 5]
구성 지침은 다중 가상 스토리지 구성을 참조하세요.
혼합 구성#
GitLab을 다음의 조합으로 사용하도록 구성할 수 있습니다:
-
독립 실행형 Gitaly 인스턴스(직접 Gitaly 스토리지).
-
Gitaly Cluster (Praefect) 가상 스토리지.
혼합 구성은 다음과 같은 경우에 사용할 수 있습니다:
-
독립 실행형 Gitaly에서 Gitaly Cluster (Praefect)로 점진적으로 마이그레이션하는 경우.
-
일부 리포지터리는 고가용성이 필요하고 다른 리포지터리는 그렇지 않은 경우.
-
중요한 리포지터리에만 Gitaly Cluster (Praefect)를 사용하여 비용을 최적화하려는 경우.
혼합 구성에서 각 스토리지는 GitLab에서 독립적으로 구성됩니다:
-
독립 실행형 Gitaly 스토리지는 Gitaly 노드에 직접 연결됩니다.
-
Gitaly Cluster (Praefect) 스토리지는 Praefect 로드 밸런서에 연결됩니다.
GitLab은 독립 실행형인지 클러스터인지에 관계없이 구성된 모든 스토리지를 동등하게 처리합니다. 새 리포지터리를 생성할 때 GitLab은 구성된 스토리지 가중치와 사용 가능한 용량을 기반으로 스토리지를 선택합니다.
%%{init: { "fontFamily": "GitLab Sans" }}%% graph TD accTitle: Mixed configuration accDescr: Example result of mixed configuration, with a Gitaly Cluster (Praefect) and standalone Gitaly configured together.
GitLab[[GitLab server]]
Praefect[(Praefect cluster)]
Standalone1[(Standalone gitaly)]
GitLab -->|cluster storage| Praefect
GitLab -->|default storage| Standalone1
Praefect --> G1[Gitaly node 1]
Praefect --> G2[Gitaly node 2]
Praefect --> G3[Gitaly node 3]
자세한 내용은 다음을 참조하세요:
-
구성 예시는 혼합 구성.
-
마이그레이션 지침은 기존 GitLab 인스턴스에 TCP 사용.
스토리지 레이아웃#
스토리지 레이아웃은 Gitaly Cluster (Praefect)의 내부 세부 사항이며 릴리즈 간에 안정적으로 유지되는 것이 보장되지 않습니다.
여기에 있는 정보는 정보 제공 목적 및 디버깅에 도움을 주기 위한 것입니다. 디스크에서 리포지터리를 직접 변경하는 것은 지원되지 않으며 오류나 변경 사항이 덮어씌워질 수 있습니다.
Gitaly Cluster (Praefect) 가상 스토리지는 단일 스토리지처럼 보이는 추상화를 제공하지만 실제로는 여러 물리적 스토리지로 구성됩니다. Gitaly Cluster (Praefect)는 각 작업을 각 물리적 스토리지에 복제해야 합니다. 작업은 일부 물리적 스토리지에서는 성공하지만 다른 스토리지에서는 실패할 수 있습니다.
부분적으로 적용된 작업은 다른 작업에서 문제를 일으키고 시스템을 복구할 수 없는 상태로 만들 수 있습니다. 이러한 유형의 문제를 방지하기 위해 각 작업은 완전히 적용되거나 전혀 적용되지 않아야 합니다. 작업의 이 속성을 원자성이라고 합니다.
GitLab은 리포지터리 스토리지의 스토리지 레이아웃을 제어합니다. GitLab은 리포지터리 스토리지에 리포지터리를 생성, 삭제, 이동할 위치를 지시합니다. 이러한 작업은 여러 물리적 스토리지에 적용될 때 원자성 문제를 일으킵니다. 예를 들어:
-
GitLab이 복제본 중 하나를 사용할 수 없을 때 리포지터리를 삭제합니다.
-
GitLab이 나중에 리포지터리를 다시 생성합니다.
그 결과, 삭제 시 사용할 수 없었던 오래된 복제본이 충돌을 일으키고 리포지터리 재생성을 방해할 수 있습니다.
이러한 원자성 문제는 과거에 다음과 같은 여러 문제를 야기했습니다:
-
Gitaly Cluster (Praefect)를 사용하는 보조 사이트로의 Geo 동기화.
-
백업 복원.
-
리포지터리 스토리지 간 리포지터리 이동.
Gitaly Cluster (Praefect)는 부분적으로 적용된 작업으로 인해 발생할 수 있는 충돌을 방지하는 특별한 레이아웃으로 디스크에 리포지터리를 저장하여 이러한 작업의 원자성을 제공합니다.
클라이언트 생성 복제본 경로#
리포지터리는 Gitaly 클라이언트에 의해 결정된 상대 경로로 스토리지에 저장됩니다. 이러한 경로는
@cluster 접두사로 시작하지 않는 것으로 식별할 수 있습니다. 상대 경로는
해시 스토리지 스키마를 따릅니다.
Praefect 생성 복제본 경로#
Gitaly Cluster (Praefect)가 리포지터리를 생성할 때 리포지터리에 리포지터리 ID라고 하는 고유하고 영구적인 ID를 할당합니다. 리포지터리 ID는 Gitaly Cluster (Praefect) 내부의 것이며 GitLab의 다른 곳에 있는 ID와 관련이 없습니다. 리포지터리가 Gitaly Cluster (Praefect)에서 제거된 후 다시 이동되면 리포지터리에 새 리포지터리 ID가 할당되며 Gitaly Cluster (Praefect)의 관점에서 다른 리포지터리가 됩니다. 리포지터리 ID의 시퀀스는 항상 증가하지만 시퀀스에 공백이 있을 수 있습니다.
리포지터리 ID는 클러스터의 각 리포지터리에 대해 복제본 경로라는 고유한 스토리지 경로를 도출하는 데 사용됩니다. 리포지터리의 복제본은 스토리지의 동일한 복제본 경로에 모두 저장됩니다. 복제본 경로는 상대 경로와 다릅니다:
-
상대 경로는 Gitaly 클라이언트가 가상 스토리지와 함께 리포지터리를 식별하는 데 사용하는 이름으로, 고유합니다.
-
복제본 경로는 물리적 스토리지의 실제 물리적 경로입니다.
Praefect는 클라이언트 요청을 처리할 때 RPC의 리포지터리를 가상 (가상 스토리지, 상대 경로) 식별자에서 물리적 리포지터리
(스토리지, 복제본_경로) 식별자로 변환합니다.
복제본 경로의 형식:
-
객체 풀은
@cluster/pools/<xx>/<xx>/<리포지터리 ID>입니다. 객체 풀은 다른 리포지터리와 다른 디렉터리에 저장됩니다. 하우스키핑의 일부로 가지치기를 방지하기 위해 Gitaly가 식별할 수 있어야 합니다. 객체 풀을 가지치기하면 연결된 리포지터리에서 데이터 손실이 발생할 수 있습니다. -
다른 리포지터리는
@cluster/repositories/<xx>/<xx>/<리포지터리 ID>입니다.
예를 들어 @cluster/repositories/6f/96/54771.
복제본 경로의 마지막 구성 요소인 54771은 리포지터리 ID입니다. 이를 사용하여 디스크에서 리포지터리를 식별할 수 있습니다.
<xx>/<xx>는 리포지터리 ID의 문자열 표현의 SHA256 해시의 처음 4개 16진수입니다. 이
숫자는 일부 파일 시스템에서 문제를 일으킬 수 있는 너무 큰 디렉터리를 방지하기 위해 리포지터리를 하위 디렉터리로 균등하게 분산시키는 데 사용됩니다. 이 경우 54771은
6f960ab01689464e768366d3315b3d3b2c28f38761a58a70110554eb04d582f7로 해시되어 처음 4자리가 6f와 96입니다.
디스크에서 리포지터리 식별#
praefect metadata 하위 명령을 사용하여 다음을 수행합니다:
-
메타데이터 저장소에서 리포지터리의 가상 스토리지와 상대 경로를 검색합니다. 해시 스토리지 경로를 얻은 후 Rails 콘솔을 사용하여 프로젝트 경로를 검색할 수 있습니다.
-
다음 중 하나를 사용하여 클러스터에서 리포지터리가 저장된 위치를 찾습니다:
가상 스토리지 및 상대 경로.
- 리포지터리 ID.
디스크의 리포지터리에는 Git 구성 파일에 프로젝트 경로도 포함되어 있습니다. 구성 파일은 리포지터리의 메타데이터가 삭제된 경우에도 프로젝트 경로를 확인하는 데 사용할 수 있습니다. 해시 스토리지 문서의 지침을 따르세요.
작업의 원자성#
Gitaly Cluster (Praefect)는 리포지터리 생성, 삭제, 이동 작업의 원자성을 보장하기 위해 스토리지 레이아웃과 함께 PostgreSQL 메타데이터 저장소를 사용합니다. 디스크 작업은 여러 스토리지에 원자적으로 적용할 수 없습니다. 하지만 PostgreSQL은 메타데이터 작업의 원자성을 보장합니다. Gitaly Cluster (Praefect)는 실패한 작업이 항상 메타데이터를 일관되게 유지하는 방식으로 작업을 모델링합니다. 성공적인 작업 후에도 디스크에 오래된 상태가 남아 있을 수 있습니다. 이 상황은 예상된 것이며 남겨진 상태는 향후 작업을 방해하지 않지만 정리가 수행될 때까지 디스크 공간을 불필요하게 사용할 수 있습니다.
스토리지에서 남은 리포지터리를 정리하는 백그라운드 크롤러에 대한 지속적인 작업이 있습니다.
리포지터리 생성#
리포지터리를 생성할 때 Praefect는 다음을 수행합니다:
-
PostgreSQL에서 리포지터리 ID를 예약합니다. 이는 원자적이며 두 개의 생성이 동일한 ID를 받지 않습니다.
-
리포지터리 ID에서 파생된 복제본 경로의 Gitaly 스토리지에 복제본을 생성합니다.
-
리포지터리가 디스크에 성공적으로 생성된 후 메타데이터 레코드를 생성합니다.
두 개의 동시 작업이 동일한 리포지터리를 생성하더라도 스토리지의 다른 디렉터리에 저장되어 충돌하지 않습니다. 먼저 완료된 작업이 메타데이터 레코드를 생성하고 다른 작업은 "already exists" 오류로 실패합니다. 실패한 생성은 스토리지에 남겨진 리포지터리를 남깁니다. 스토리지에서 남겨진 리포지터리를 정리하는 백그라운드 크롤러에 대한 지속적인 작업이 있습니다.
리포지터리 ID는 PostgreSQL의 repositories_repository_id_seq에서 생성됩니다. 앞의 예시에서 실패한 작업은 리포지터리를 성공적으로 생성하지 못하면서 하나의 리포지터리 ID를 사용했습니다. 실패한 리포지터리 생성은 리포지터리 ID에 공백이 생기는 원인이 됩니다.
리포지터리 삭제#
리포지터리는 메타데이터 레코드를 제거하여 삭제됩니다. 메타데이터 레코드가 삭제되는 즉시 리포지터리는 논리적으로 존재하지 않게 됩니다. PostgreSQL은 제거의 원자성을 보장하며 동시 삭제는 "not found" 오류로 실패합니다. 메타데이터 레코드를 성공적으로 삭제한 후 Praefect는 스토리지에서 복제본을 제거하려고 시도합니다. 이것이 실패하여 스토리지에 남겨진 상태가 생길 수 있습니다. 남겨진 상태는 결국 정리됩니다.
리포지터리 이동#
Gitaly와 달리 Gitaly Cluster (Praefect)는 스토리지의 리포지터리를 이동하지 않고 메타데이터 저장소의 리포지터리의 상대 경로를 업데이트하여 가상으로만 리포지터리를 이동합니다.
구성 요소#
Gitaly Cluster (Praefect)는 여러 구성 요소로 이루어집니다:
-
요청을 분산하고 Praefect 노드에 대한 내결함성 액세스를 제공하는 로드 밸런서.
-
클러스터를 관리하고 Gitaly 노드로 요청을 라우팅하는 Praefect 노드.
-
클러스터 메타데이터를 유지하는 PostgreSQL 데이터베이스 및 Praefect의 데이터베이스 연결 풀링에 권장되는 PgBouncer.
-
리포지터리 스토리지 및 Git 액세스를 제공하는 Gitaly 노드.
아키텍처#
Praefect는 Gitaly용 라우터 및 트랜잭션 관리자이며 Gitaly Cluster (Praefect)를 실행하는 데 필요한 구성 요소입니다.
[
](/19.2/administration/gitaly/praefect/img/praefect_architecture_v12_10.png)
자세한 내용은 Gitaly 고가용성(HA) 설계를 참조하세요.
기능#
Gitaly Cluster (Praefect)는 다음 기능을 제공합니다:
-
Gitaly 노드 간 분산 읽기.
-
보조 복제본의 강력한 일관성.
-
향상된 이중화를 위한 리포지터리의 복제 인수.
-
기본 Gitaly 노드에서 보조 Gitaly 노드로의 자동 페일오버.
-
복제 큐가 비어 있지 않은 경우 가능한 데이터 손실 보고.
에픽 1489에서 수평 읽기 분산을 포함한 제안된 개선 사항을 따르세요.
분산 읽기#
Gitaly Cluster (Praefect)는 가상 스토리지에 구성된 Gitaly 노드 전반에 걸친 읽기 작업 분산을 지원합니다.
ACCESSOR 옵션으로 표시된 모든 RPC는 최신 상태이고 정상적인 Gitaly 노드로 리디렉션됩니다.
예를 들어 GetBlob.
이 맥락에서 "최신 상태"란 다음을 의미합니다:
-
이 Gitaly 노드에 대해 예약된 복제 작업이 없습니다.
-
마지막 복제 작업이 완료 상태입니다.
다음과 같은 경우 요청을 처리하기 위해 기본 노드가 선택됩니다:
-
최신 상태의 노드가 없는 경우.
-
노드 선택 중 다른 오류가 발생하는 경우.
대규모로 자주 수정되는 리포지터리(예: 수 기가바이트의 모노레포)가 있는 경우, 변경 사항이 Praefect가 보조 노드에 복제할 수 있는 속도보다 빠르게 들어오면 기본 노드가 대부분 또는 모든 요청을 처리할 수 있습니다. 이런 상황이 발생하면 CI/CD job 및 기타 리포지터리 트래픽이 기본 노드의 용량에 의해 병목 현상을 겪게 됩니다.
Prometheus를 사용하여 읽기 분산을 모니터링할 수 있습니다.
강력한 일관성#
Gitaly Cluster (Praefect)는 모든 정상적이고 최신 상태의 복제본에 변경 사항을 동기적으로 작성하여 강력한 일관성을 제공합니다. 복제본이 트랜잭션 시 오래되었거나 정상이 아닌 경우 쓰기는 비동기적으로 복제됩니다.
강력한 일관성은 기본 복제 방법입니다. 일부 작업의 하위 집합은 여전히 강력한 일관성 대신 복제 job (최종 일관성)을 사용합니다. 자세한 내용은 강력한 일관성 에픽을 참조하세요.
강력한 일관성을 사용할 수 없는 경우 Gitaly Cluster (Praefect)는 최종 일관성을 보장합니다. 이 경우 Gitaly Cluster (Praefect)는 기본 Gitaly 노드에 쓰기가 발생한 후 보조 Gitaly 노드로 모든 쓰기를 복제합니다.
강력한 일관성 모니터링에 대한 자세한 내용은 Gitaly Cluster (Praefect) 모니터링을 참조하세요.
복제 인수#
복제 인수는 Gitaly Cluster (Praefect)가 주어진 리포지터리의 복사본을 유지하는 수입니다. 더 높은 복제 인수는:
-
더 나은 이중화 및 읽기 워크로드 분산을 제공합니다.
-
더 높은 스토리지 비용을 초래합니다.
기본적으로 Gitaly Cluster (Praefect)는 리포지터리를 가상 스토리지의 모든 스토리지에 복제합니다.
구성 정보는 복제 인수 구성을 참조하세요.
Gitaly Cluster (Praefect) 업그레이드#
Gitaly Cluster (Praefect)를 업그레이드하려면 무중단 업그레이드 문서를 따르세요.
Gitaly Cluster (Praefect)를 이전 버전으로 롤백#
Gitaly Cluster (Praefect)를 이전 버전으로 롤백해야 하는 경우 일부 Praefect 데이터베이스 마이그레이션을 되돌려야 할 수 있습니다.
여러 Praefect 노드를 가정하여 Gitaly Cluster (Praefect)를 롤백하려면:
모든 Praefect 노드에서 Praefect 서비스를 중지합니다:
gitlab-ctl stop praefect
Praefect 노드 중 하나에서 GitLab 패키지를 이전 버전으로 롤백합니다.
롤백된 노드에서 Praefect 마이그레이션 상태를 확인합니다:
sudo -u git -- /opt/gitlab/embedded/bin/praefect -config /var/opt/gitlab/praefect/config.toml sql-migrate-status
APPLIED 칼럼에 unknown migration이 있는 마이그레이션 수를 세어봅니다.
롤백되지 않은 Praefect 노드에서 어떤 마이그레이션을 되돌릴지 검증하기 위해 롤백 드라이 런을 수행합니다. 은
롤백된 노드에서 보고한 알 수 없는 마이그레이션 수입니다.
sudo -u git -- /opt/gitlab/embedded/bin/praefect -config /var/opt/gitlab/praefect/config.toml sql-migrate
결과가 올바른 것으로 보이면 -f 옵션과 함께 동일한 명령을 실행하여 마이그레이션을 되돌립니다:
sudo -u git -- /opt/gitlab/embedded/bin/praefect -config /var/opt/gitlab/praefect/config.toml sql-migrate -f
나머지 Praefect 노드에서 GitLab 패키지를 롤백하고 Praefect 서비스를 다시 시작합니다:
gitlab-ctl start praefect
Gitaly Cluster (Praefect)로 마이그레이션#
Gitaly Cluster (Praefect)에는 일부 [알려진 문제](/19.2/administration/gitaly/praefect/#known-issues)가 있습니다. 계속하기 전에 다음 정보를 검토하세요.
Gitaly Cluster (Praefect)로 마이그레이션하기 전에:
-
Gitaly Cluster (Praefect) 배포 전을 검토합니다.
-
개선 사항 및 버그 수정을 최대한 활용하기 위해 가능한 최신 버전의 GitLab으로 업그레이드합니다.
Gitaly Cluster (Praefect)로 마이그레이션하려면:
-
필요한 스토리지를 생성합니다. 리포지터리 스토리지 권장 사항을 참조하세요.
-
Gitaly Cluster (Praefect)를 생성하고 구성합니다.
-
아직 구성되지 않은 경우 기존 Gitaly 인스턴스를 TCP를 사용하도록 구성합니다.
-
리포지터리를 이동합니다. Gitaly Cluster (Praefect)로 마이그레이션하려면 Gitaly Cluster (Praefect) 외부에 저장된 기존 리포지터리를 이동해야 합니다. 자동 마이그레이션은 없지만 이동은 GitLab API로 예약할 수 있습니다.
default 리포지터리 스토리지를 사용하지 않더라도 구성되어 있어야 합니다.
이 제한에 대해 자세히 읽기.
Kubernetes의 Gitaly 차트에서 마이그레이션하려면 특정 마이그레이션 지침을 따르세요.
Gitaly Cluster (Praefect)에서 마이그레이션#
Gitaly Cluster (Praefect)의 제한 사항과 트레이드오프가 환경에 적합하지 않은 것으로 판단되면 Gitaly Cluster (Praefect)에서 샤딩된 Gitaly 인스턴스로 마이그레이션할 수 있습니다:
Kubernetes의 Gitaly Cluster#
-
Status: Beta
History
Gitaly Cluster (Praefect)는 인스턴스 전반에 데이터를 복제하여 데이터 및 서비스 고가용성 측면을 해결합니다.