Geo (개발)

Geo는 GitLab 인스턴스를 연결하는 기능을 합니다. 한 GitLab 인스턴스가 기본 사이트로 지정되어 여러 보조 사이트와 함께 실행될 수 있습니다. Geo는 아래 다이어그램에서 볼 수 있으며 이 문서에서 자세히 설명되어 있는 여러 구성요소를 조율합니다.

Geo 아키텍처 다이어그램

복제 레이어

Geo는 다양한 구성 요소에 대한 복제를 처리합니다:

  • 데이터베이스: 캐시 및 작업을 제외한 전체 애플리케이션을 포함합니다.
  • Git 저장소: 프로젝트와 위키를 모두 포함합니다.
  • Blob: 이슈에 첨부된 이미지부터 CI의 원시 로그 및 에셋과 같은 모든 것을 포함합니다.

데이터베이스 복제를 제외한 모든 것은 보조 사이트에서 Geo Log Cursor에 의해 조율됩니다.

복제 상태

다음 다이어그램은 복제 작업 방법을 설명합니다. 명확함을 위해 특정 전이가 생략되었습니다.

stateDiagram-v2 대기 중 --> 시작됨 시작됨 --> 동기화됨 시작됨 --> 실패함 동기화됨 --> 대기 중: 다시 동기화를 위한 표시 실패함 --> 대기 중: 다시 동기화를 위한 표시 실패함 --> 시작됨: 재시도

Geo Log Cursor 데몬

Geo Log Cursor 데몬은 각 보조 사이트에서 실행되는 별도의 프로세스입니다. 이 데몬은 Geo 이벤트 로그를 모니터링하여 새 이벤트마다 특정 이벤트 유형에 대한 백그라운드 작업을 생성합니다.

예를 들어, 저장소가 업데이트되면 Geo 기본 사이트에서 연관된 저장소가 업데이트된 이벤트를 가진 Geo 이벤트를 생성합니다. Geo Log Cursor 데몬은 이 이벤트를 가져와 Geo::ProjectSyncWorker 작업을 예약하며 이 작업은 Geo::RepositorySyncService를 사용하여 저장소를 업데이트합니다.

Geo Log Cursor 데몬은 자동으로 고가용성 모드에서 작동할 수 있습니다. 데몬은 때때로 잠금을 획들하려고 시도하고 한 번 획득하게 되면 활성 데몬처럼 동작합니다.

동일한 사이트에서 추가로 실행 중인 데몬은 대기 모드에 있어 활성 데몬이 잠금을 해제할 경우 작업을 다시 수행할 수 있도록 준비돼 있습니다.

우리는 작은 TTL을 갖는 ExclusiveLease 잠금 유형을 사용하여 계속 갱신되는 전역 잠금을 구현할 수 있습니다.

풀링 주기마다 잠금을 갱신하거나 재획득하지 못하면, 데몬은 대기 모드로 전환합니다.

데이터베이스 복제

Geo는 스트리밍 복제를 사용하여 데이터베이스를 기본에서 보조 사이트로 복제합니다. 이 복제로 보조 사이트가 데이터베이스에 저장된 모든 데이터에 액세스할 수 있어 사용자가 보조 사이트에 로그인하여 이슈 및 병합 요청과 같은 모든 내용을 읽을 수 있습니다.

저장소 복제

Geo는 또한 저장소를 복제합니다. 각 보조 사이트는 추적 데이터베이스의 모든 저장소 상태를 추적합니다.

저장소가 다음과 같은 몇 가지 방법으로 복제됩니다:

프로젝트 레지스트리

Geo::ProjectRegistry 클래스는 저장소 복제 상태를 추적하는 데 사용되는 모델을 정의합니다. 주 데이터베이스의 각 프로젝트에 대해 추적 데이터베이스의 하나의 레코드가 유지됩니다.

다음과 같은 사항을 저장소에 대해 기록합니다:

  • 최근 동기화한 시간.
  • 마지막으로 성공적으로 동기화한 시간.
  • 재동기화가 필요한 지 여부.
  • 재시도해야 하는 시간.
  • 재시도 횟수.
  • 확인되었는지 여부 및 그 때.

이러한 속성을 프로젝트 위키에 대한 전용 컬럼에도 저장합니다.

저장소 동기화 워커

Geo::RepositorySyncWorker 클래스는 주기적으로 백그라운드에서 실행되며 업데이트가 필요한 프로젝트를 찾습니다. 이러한 프로젝트들은 다음과 같을 수 있습니다:

  • 동기화되지 않은 프로젝트: 보조 사이트에 아직 동기화되지 않은 프로젝트로 아직 존재하지 않습니다.
  • 최근 업데이트된 프로젝트: Geo::ProjectRegistry 모델의 last_repository_successful_sync_at 타임스탬프보다 최근인 last_repository_updated_at 타임스탬프를 가진 프로젝트.
  • 수동으로: 관리자가 Geo 관리 영역에서 저장소를 수동으로 다시 동기화할 수 있습니다.

RETRIES_BEFORE_REDOWNLOAD번의 시도로 저장소를 가져오는 데 실패하면, Geo는 이를 재다운로드라고 합니다. 저장소를 @geo-temporary 디렉토리에 깨끗한 클론을 수행합니다. 성공하면 새로 클론한 저장소로 주 저장소를 대체합니다.

Blob 복제

업로드와 같은 Blob(업로드 문서를 참조하세요), LFS 객체 및 CI 작업 아티팩트와 같은 Blob은 Self-Service Framework를 사용하여 보조 사이트로 복제됩니다. 동기화 상태를 추적하기 위해 각 모델에는 해당 레지스트리 테이블이 있으며, 예를 들어 UploadPostgreSQL Geo 추적 데이터베이스Geo::UploadRegistry를 가지고 있습니다.

서비스 간 Blob 복제 성공 시나리오 워크플로우

작업 아티팩트는 다이어그램에서 예시로 사용되며 Blob의 한 예시로 사용됩니다.

새 작업 아티팩트 복제

기본 사이트:

sequenceDiagram participant R as Runner participant P as Puma participant DB as PostgreSQL participant SsP as Secondary site PostgreSQL R->>P: 아티팩트 업로드 P->>DB: `ci_job_artifacts` 행 삽입 P->>DB: `geo_events` 행 삽입, "ID 123인 작업 아티팩트가 업데이트되었습니다" P->>DB: `geo_event_log` 행 삽입, `geo_events` 행을 가리킴 (일부 레거시 논리를 기반으로 SSF를 구축했기 때문) DB->>SsP: 행 복제
  • Runner가 아티팩트를 업로드합니다
  • Pumaci_job_artifacts 행을 삽입합니다
  • Puma가 “ID 123인 작업 아티팩트가 업데이트되었습니다” 등의 데이터로 geo_events 행을 삽입합니다
  • Puma가 geo_event_log 행을 삽입하고 geo_events 행을 가리킵니다 (일부 레거시 논리를 기반으로 SSF를 구축했기 때문)
  • PostgreSQL 스트리밍 복제가 읽기 레플리카에 행을 삽입합니다

PostgreSQL DB 행이 복제된 후의 보조 사이트:

sequenceDiagram participant DB as PostgreSQL participant GLC as Geo Log Cursor participant R as Redis participant S as Sidekiq participant TDB as PostgreSQL Tracking DB participant PP as Primary site Puma GLC->>DB: `geo_event_log` 조회 GLC->>DB: `geo_events` 조회 GLC->>R: `Geo::EventWorker`를 큐에 넣음 S->>R: `Geo::EventWorker` 실행 S->>TDB: `job_artifact_registry`에 "시작 동기화" 삽입 S->>PP: <기본 사이트 내부 URL>로부터 `job_artifact/123` 검색 S->>TDB: `job_artifact_registry` 업데이트, "동기화됨"
  • Geo Log Cursor 루프가 새 geo_event_log 행을 찾음
  • Geo Log Cursor가 geo_events 행을 처리함
    • Geo Log Cursor가 geo_events 행 데이터를 통과시키며 Geo::EventWorker 작업을 큐에 넣음
  • SidekiqGeo::EventWorker 작업을 처리함
    • Sidekiq가 PostgreSQL Geo Tracking Databasejob_artifact_registry 행을 삽입하고 “시작 동기화”로 표시함, 이는 동시에 여러 인스턴스가 실행되는 것을 방지하기 위해 배타적인 레이스를 사용합니다
    • Sidekiq가 기본 Geo 사이트의 API 엔드포인트에서 GET 요청을 수행하고 파일을 다운로드함
    • Sidekiq가 job_artifact_registry 행을 “동기화됨” 및 “검증 대기 중”으로 표시함
기존 작업 아티팩트의 백필
  • 시스템 관리자가 Geo 없는 기존 GitLab 사이트를 보유함
  • 기존 CI 작업 및 작업 아티팩트가 있음
  • 시스템 관리자가 새 GitLab 사이트를 설정하고 보조 Geo 사이트로 구성함

보조 사이트:

매분마다 두 개의 크론 작업이 실행됨: Geo::Secondary::RegistryConsistencyWorkerGeo::RegistrySyncWorker. 아래 워크플로우는 이를 기준으로 나눠짐.

sequenceDiagram participant SC as Sidekiq-cron participant R as Redis participant S as Sidekiq participant DB as PostgreSQL participant TDB as PostgreSQL Tracking DB SC->>R: `Geo::Secondary::RegistryConsistencyWorker` 실행 큐에 넣음 S->>R: `Geo::Secondary::RegistryConsistencyWorker` 실행 S->>DB: `ci_job_artifacts` 조회 S->>TDB: `job_artifact_registry` 조회 S->>TDB: `job_artifact_registry`에 삽입
  • Sidekiq-cron이 매분마다 Geo::Secondary::RegistryConsistencyWorker 작업을 큐에 등록함. 활발하게 작업 중인 한(행 생성 및 삭제)이 작업은 즉시 자체를 다시 큐에 넣습니다. 이 작업은 동시에 여러 인스턴스가 실행되는 것을 방지하기 위해 배타적인 레이스를 사용합니다
  • SidekiqGeo::Secondary::RegistryConsistencyWorker 작업을 처리함
    • Sidekiq가 최대 10000개의 행까지 ci_job_artifacts 테이블 조회함
    • Sidekiq가 최대 10000개의 행까지 job_artifact_registry 테이블 조회함
    • Sidekiq가 기존 작업 아티팩트에 해당하는 PostgreSQL Geo Tracking Databasejob_artifact_registry 행을 삽입함
sequenceDiagram participant SC as Sidekiq-cron participant R as Redis participant S as Sidekiq participant DB as PostgreSQL participant TDB as PostgreSQL Tracking DB participant PP as Primary site Puma SC->>R: `Geo::RegistrySyncWorker` 실행 큐에 넣음 S->>R: `Geo::RegistrySyncWorker` 실행 S->>TDB: `*_registry` 테이블 조회 S->>R: `Geo::EventWorker` 실행 큐에 넣음 S->>R: `Geo::EventWorker` 실행 S->>TDB: `job_artifact_registry`에 "시작 동기화" 삽입 S->>PP: <기본 사이트 내부 URL>/geo/retrieve/job_artifact/123 GET S->>TDB: `job_artifact_registry` 업데이트, "동기화됨"
  • Sidekiq-cron이 매분마다 Geo::RegistrySyncWorker 작업을 큐에 등록함. 활발하게 작업 중인 한(행 생성 및 삭제)이 작업은 최대 1시간 동안 동기화 작업을 예약합니다. 이 작업은 동시에 여러 인스턴스가 실행되는 것을 방지하기 위해 배타적인 레이스를 사용합니다
  • SidekiqGeo::RegistrySyncWorker 작업을 처리함
    • Sidekiq가 PostgreSQL Geo Tracking Database의 모든 registry 테이블을 “시도하지 않은 동기화” 행을 조회하고 각 테이블에서 행을 번갈아가며 인메모리 큐에 추가함
    • 이전 단계에서 1000개 보다 적은 행을 반환했다면, Sidekiq는 “동기화하지 않은 실패 및 재시도 준비” 행을 조회하고 이를 인메모리 큐에 추가함
    • Sidekiq가 인메모리 큐의 각 항목에 대해 “ID 123인 작업 아티팩트가 업데이트되었습니다”와 같은 인수로 Geo::EventWorker 작업을 큐에 등록하고 enqueued Sidekiq 작업 ID를 추적함
    • “최대 동시성 제한” 설정에 도달하면 Sidekiq가 Geo::EventWorker 작업을 더 이상 큐에 넣지 않음
    • Sidekiq가 더 이상 할 작업이 없을 때까지 이러한 작업을 반복함
  • Sidekiq가 Geo::EventWorker 작업을 처리함
    • Sidekiq가 job_artifact_registry 행을 “시작 동기화”로 표시함
    • Sidekiq가 기본 Geo 사이트의 API 엔드포인트에서 GET 요청을 수행하고 파일을 다운로드함
    • Sidekiq가 job_artifact_registry 행을 “동기화됨” 및 “검증 대기 중”으로 표시함
새 작업 아티팩트 확인

기본 사이트:

sequenceDiagram participant Ru as Runner participant P as Puma participant DB as PostgreSQL participant SC as Sidekiq-cron participant Rd as Redis participant S as Sidekiq participant F as Filesystem Ru->>P: 아티팩트 업로드 P->>DB: `ci_job_artifacts` 삽입 P->>DB: `ci_job_artifact_states` 삽입 SC->>Rd: `Geo::VerificationCronWorker`를 큐에 넣음 S->>Rd: `Geo::VerificationCronWorker` 픽업 S->>DB: `ci_job_artifact_states` 쿼리 S->>Rd: `Geo::VerificationBatchWorker`를 큐에 넣음 S->>Rd: `Geo::VerificationBatchWorker` 픽업 S->>DB: `ci_job_artifact_states` 업데이트, "시작됨" S->>F: 파일 체크섬 S->>DB: `ci_job_artifact_states` 업데이트, "완료됨"
  • Runner가 아티팩트를 업로드합니다.
  • Pumaci_job_artifacts 행을 생성합니다.
  • Puma는 검증 상태를 저장하기 위해 ci_job_artifact_states 행을 생성합니다.
    • 해당 행은 “검증 대기 중”으로 표시됩니다.
  • Sidekiq-cron은 매 분마다 Geo::VerificationCronWorker 작업을 큐에 넣습니다.
  • Sidekiqci_job_artifact_states에서 “검증 대기 중” 또는 “검증 실패 및 재시도 준비”로 표시된 행의 수를 쿼리합니다.
    • “최대 검증 동시성” 설정으로 제한된 하나 이상의 Geo::VerificationBatchWorker 작업을 큐에 넣습니다.
  • Sidekiq는 Geo::VerificationBatchWorker 작업을 픽업합니다.
    • PostgreSQL에서 이전 단계에서 10개 미만의 행을 산출했다면, Sidekiq는 “검증 대기 중”으로 표시된 행을 위해 ci_job_artifact_states를 쿼리합니다.
    • 각 행에 대해
      • Sidekiq는 “검증 시작됨”으로 표시합니다.
      • Sidekiq는 파일의 SHA256 체크섬을 가져옵니다.
      • Sidekiq는 행에 체크섬을 저장하고 “검증 완료됨”으로 표시합니다.
      • 이제 보조 Geo 사이트에서 이 체크섬을 비교할 수 있습니다.

보조 사이트:

sequenceDiagram participant SC as Sidekiq-cron participant R as Redis participant S as Sidekiq participant TDB as PostgreSQL Tracking DB participant F as Filesystem participant DB as PostgreSQL SC->>R: `Geo::VerificationCronWorker`를 큐에 넣음 S->>R: `Geo::VerificationCronWorker` 픽업 S->>TDB: `job_artifact_registry` 쿼리 S->>R: `Geo::VerificationBatchWorker`를 큐에 넣음 S->>R: `Geo::VerificationBatchWorker` 픽업 S->>TDB: `job_artifact_registry` 업데이트, "시작됨" S->>F: 파일 체크섬 S->>DB: `ci_job_artifact_states` 쿼리 S->>TDB: `job_artifact_registry` 업데이트, "완료됨"
  • 아티팩트가 성공적으로 동기화되면 “검증 대기 중” 상태가 됩니다.
  • Sidekiq-cron은 매 분마다 Geo::VerificationCronWorker 작업을 큐에 넣습니다.
  • Sidekiq은 “검증 대기 중”으로 표시된 행의 수를 위해 PostgreSQL Geo Tracking Databasejob_artifact_registry를 쿼리합니다.
    • “최대 검증 동시성” 설정으로 제한된 하나 이상의 Geo::VerificationBatchWorker 작업을 큐에 넣습니다.
  • Sidekiq는 Geo::VerificationBatchWorker 작업을 픽업합니다.
    • PostgreSQL Geo 추적 데이터베이스의 job_artifact_registry에서 “검증 대기 중”으로 표시된 행을 쿼리합니다.
    • 이전 단계에서 10개 미만의 행을 산출했다면, Sidekiq는 “검증 대기 중”으로 표시된 행을 위해 job_artifact_registry를 쿼리합니다.
    • 각 행에 대해
      • Sidekiq는 “검증 시작됨”으로 표시합니다.
      • Sidekiq는 파일의 SHA256 체크섬을 가져옵니다.
      • Sidekiq는 체크섬을 행에 저장합니다.
      • Sidekiq는 PostgreSQL이 복제한 ci_job_artifact_states의 체크섬과 비교합니다.
      • 체크섬이 일치한다면, Sidekiq는 job_artifact_registry 행을 “검증 완료됨”으로 표시합니다.

인증

파일 전송을 인증하려면 각 GeoNode 레코드에 두 개의 필드가 있습니다.

  • 공개 액세스 키(access_key 필드).
  • 비밀 액세스 키(secret_access_key 필드).

보조 사이트는 JWT 요청을 통해 자체를 인증합니다. 보조 사이트가 파일을 다운로드하려는 경우 Authorization 헤더와 함께 HTTP 요청을 보냅니다.

Authorization: GL-Geo <access_key>:<JWT 페이로드>

기본 사이트는 access_key 필드를 사용하여 해당 보조 사이트를 찾고 JWT 페이로드를 해독합니다. 이 페이로드에는 파일 요청을 식별하는 추가 정보가 포함되어 있습니다. 이를 통해 보조 사이트가 올바른 데이터베이스 ID에 대한 올바른 파일을 다운로드합니다. 예를 들어, LFS 객체의 경우 요청에 파일의 SHA256 합계를 포함해야 합니다. 예시 JWT 페이로드는 다음과 같습니다.

{"data": {sha256: "31806bb23580caab78040f8c45d329f5016b0115"}, iat: "1234567890"}

요청된 파일이 요청된 SHA256 합계와 일치하면 Geo 기본 사이트는 X-Sendfile 기능을 통해 데이터를 보내며, 이를 통해 NGINX가 Rails 또는 Workhorse를 사용하지 않고 파일 전송을 처리할 수 있습니다.

참고: JWT는 관련된 기계들 사이의 동기화된 시계를 필요로 하며, 그렇지 않으면 암호화 오류가 발생할 수 있습니다.

Geo 보조에 대한 Git Push

Git Push 프록시는 gitlab-shell 구성요소 내에 내장된 기능으로 존재합니다. 이 기능은 보조 사이트에서만 활성화되며, 보조 사이트에서 복제된 저장소에서 클론한 사용자가 동일한 URL로 push할 수 있습니다.

보조 사이트로 직접 이동되는 Git push 요청은 기본 사이트로 전송됩니다. 한편 pull 요청은 최대 효율성을 위해 계속해서 보조 사이트에서 제공됩니다.

HTTPS 및 SSH 요청은 다르게 처리됩니다.

  • HTTPS의 경우, 사용자에게 기본 사이트의 프로젝트를 가리키는 HTTP 302 Redirect가 제공됩니다. Git 클라이언트는 해당 상태 코드를 이해하고 리디렉션을 처리할 수 있습니다.
  • SSH의 경우, 리디렉션을 수행할 동등한 방법이 없기 때문에 요청을 프록시해야 합니다. 이는 gitlab-shell 내에서 수행되며, 먼저 요청을 HTTP 프로토콜로 변환한 다음 기본 사이트로 프록시합니다.

gitlab-shell 데몬은 /api/v4/allowed로부터의 응답을 기반으로 언제 프록시를 사용해야 하는지 알고 있습니다. 특별한 HTTP 300 상태 코드가 반환되고 응답 본문에 지정된 “사용자 정의 작업”을 실행합니다. 응답에는 프록시된 push 작업을 기본 사이트에서 실행할 수 있도록 하는 추가 데이터가 포함되어 있습니다.

추적 데이터베이스 사용하기

복제된 주 데이터베이스와 별도로, Geo 보조 사이트에는 자체 추적 데이터베이스가 있습니다.

추적 데이터베이스에는 보조 사이트의 상태가 포함되어 있습니다.

업그레이드의 일부로 실행해야 하는 모든 데이터베이스 마이그레이션은 각 보조 사이트의 추적 데이터베이스에 적용해야 합니다.

구성

데이터베이스 구성은 config/database.yml에 설정되어 있으며, 디렉토리 ee/db/geo에는 이 데이터베이스의 스키마와 마이그레이션에 관한 정보가 포함되어 있습니다.

데이터베이스에 대한 마이그레이션을 실행하려면 다음을 실행하세요.

rails g migration [args] [options] --database geo

Geo는 gitlab_geo 스키마가 지원될 때까지 Gitlab::Database::Migration[1.0]을 계속 사용해야 하며, 현재는 [2.0]에 대해 유효성 검사를 제외해야 합니다. 이는 마이그레이션 기본값이 2.0일 경우 개발자가 마이그레이션 파일을 수동으로 수정하여 [2.0]에서 [1.0]로 변경해야 함을 의미합니다.

자세한 정보는 Geo 마이그레이션에 Migration[2.0] 사용 가능하도록 활성화하기 문제를 참조하십시오.

추적 데이터베이스를 마이그레이션하려면 다음을 실행하세요.

bundle exec rake db:migrate:geo

검색기

Geo는 검색기(Finders)를 사용합니다. 이는 추적 데이터베이스와 주 데이터베이스에서 프로젝트/첨부 파일 등을 찾아내는 작업을 처리합니다.

Redis

보조 사이트의 Redis는 기본 사이트와 동일하게 작동합니다. 이는 캐싱, 세션 저장 및 기타 영구 데이터에 사용됩니다.

기본보조 사이트 간의 Redis 데이터 복제는 사용되지 않으므로 세션 등이 사이트 간에 공유되지 않습니다.

오브젝트 스토리지

GitLab은 기본적으로 디스크에 저장하는 데이터를 오브젝트 스토리지에 저장할 수 있습니다. 예를 들면:

  • LFS 오브젝트
  • CI 작업 아티팩트
  • 업로드

기본 설정에서 Geo는 오브젝트 스토리지에 저장된 오브젝트를 레플리케이트하지 않습니다. 상황 및 고객의 요구에 따라 고객은 다음을 할 수 있습니다:

확인

확인 상태

다음 다이어그램은 확인 작업이 진행되는 방식을 보여줍니다. 명확함을 위해 일부 허용된 전이는 생략되었습니다.

stateDiagram-v2 Pending --> Started Pending --> Disabled: No primary checksum Disabled --> Started: Primary checksum succeeded Started --> Succeeded Started --> Failed Succeeded --> Pending: Mark for reverify Failed --> Pending: Mark for reverify Failed --> Started: Retry

저장소 확인

저장소는 체크섬으로 확인됩니다.

기본 사이트는 저장소에서 체크섬을 계산합니다. 기본적으로 모든 Git 참조를 해시화하여 그 해시를 데이터베이스의 project_repository_states 테이블에 저장합니다.

보조 사이트는 동일한 작업을 수행하여 그 클론의 해시를 계산하고, 그 해시를 기본 사이트에서 계산한 값과 비교합니다. 불일치하는 경우 Geo는 불일치로 표시하고 관리자는 이를 Geo 관리 영역에서 볼 수 있습니다.

Geo 프록시

Geo 보조 사이트는 웹 요청을 기본 사이트로 프록시할 수 있습니다. 자세한 내용은 Geo 프록시(개발) 페이지를 참조하십시오.

Geo API

Geo는 다양한 구성 요소 간의 통신을 용이하게 하기 위해 외부 API를 사용합니다.

용어집

기본 사이트

기본 사이트는 Geo 설정에서 읽기-쓰기 기능을 하는 단일 사이트입니다. 이 사이트는 단일 진실의 출처이며 Geo 보조 사이트는 해당 사이트로부터 데이터를 복제합니다.

Geo 설정에서는 기본 사이트가 단 하나만 있을 수 있습니다. 모든 보조 사이트는 해당 기본 사이트에 연결합니다.

보조 사이트

보조 사이트는 다른 지리적 위치에서 실행되는 기본 사이트의 읽기 전용 복제본입니다.

스트리밍 레플리케이션

Geo는 PostgreSQL의 스트리밍 레플리케이션 기능에 의존합니다. 이 기능은 데이터베이스 데이터와 데이터베이스 스키마를 완전히 복제합니다. 데이터베이스 복제본은 읽기 전용 복사본입니다.

스트리밍 레플리케이션은 Write Ahead Logs(WAL)에 의존합니다. 이러한 로그는 복제본으로 복사되어 거기에서 다시 재생됩니다.

스트리밍 레플리케이션은 스키마도 복제하기 때문에 데이터베이스 마이그레이션은 보조 사이트에서 실행할 필요가 없습니다.

추적 데이터베이스

각 Geo 보조 사이트의 데이터베이스로 해당 사이트의 상태를 유지합니다. 자세한 내용은 추적 데이터베이스 사용를 참조하십시오.

Geo 이벤트 로그

Geo 기본 사이트는 geo_event_log 테이블에 이벤트를 저장합니다. 로그의 각 항목에는 특정 유형의 이벤트가 포함됩니다. 이 유형의 이벤트에는 다음이 있습니다:

  • 저장소 삭제 이벤트
  • 저장소 이름 바꾸기 이벤트
  • 저장소 변경 이벤트
  • 저장소 생성 이벤트
  • 해시 저장소 마이그레이션 이벤트
  • LFS 오브젝트 삭제 이벤트
  • 해시 저장소 첨부 파일 이벤트
  • 작업 아티팩트 삭제 이벤트
  • 업로드 삭제 이벤트

자세한 내용은 Geo 로그 커서 데몬을 참조하십시오.

코드 기능

Gitlab::Geo 유틸리티

Geo와 관련된 작은 유틸리티 메서드는 ee/lib/gitlab/geo.rb 파일에 들어갑니다.

이러한 메서드 중 많은 메서드는 코드 베이스 전체에서 사용되는 성능 영향을 줄이기 위해 RequestStore 클래스를 사용하여 캐시됩니다.

현재 사이트

클래스 메서드 .current_node은 현재 사이트에 대한 GeoNode 레코드를 반환합니다.

gitlab.yml에서 host, port, 및 relative_url_root 값을 사용하여 데이터베이스에서 현재 사이트를 식별합니다 (GeoNode.current_node 참조).

기본 또는 보조

현재 사이트가 기본 사이트인지 보조 사이트인지 확인하려면 .primary?.secondary? 클래스 메서드를 사용하십시오.

사이트가 활성화되지 않은 경우 두 메서드가 모두 false를 반환할 수 있습니다. 자세한 내용은 활성화를 참조하십시오.

Geo 데이터베이스 구성됨?

초기화 중에 발생하는 일부 작업을 처리할 때 추가적인 주의할 사항도 있습니다. 몇 군데에서 우리는 보조 사이트에만 존재하는 추적 데이터베이스를 사용하는지 확인하기 위해 Gitlab::Geo.geo_database_configured? 메서드를 사용합니다. 이는 새로운 사이트를 부트스트래핑하는 동안 발생할 수 있는 레이스 조건을 극복합니다.

활성화

사용자가 Geo 기능이 사용 가능한 유효한 라이선스를 가지고 있고 Geo 노드화 화면에 하나 이상의 사이트가 정의되어 있는 경우에 Geo 기능이 활성화되었다고 간주합니다. 자세한 내용은 Gitlab::Geo.enabled?Gitlab::Geo.license_allows? 메서드를 참조하십시오.

읽기 전용

모든 Geo secondary 사이트는 읽기 전용입니다.

읽기 전용 데이터베이스의 일반 원칙이 모든 Geo secondary 사이트에 적용됩니다. 따라서 Gitlab::Database.read_only? 메서드는 secondary 사이트에서 항상 true를 반환합니다.

일부 쓰기 작업이 secondary 사이트에서 허용되지 않을 때는 Gitlab::Geo.secondary? 대신 Gitlab::Database.read_only? 또는 Gitlab::Database.read_write? 가드를 추가하는 것이 좋습니다.

데이터베이스 자체는 이미 복제 설정에서 읽기 전용일 것이므로 추가 조치가 필요하지 않습니다.

새로운 기능이 Geo를 지원하는지 확인하기

Geo는 주요 및 CI 데이터베이스의 PostgreSQL 복제에 의존하므로 새 테이블이나 필드를 추가하는 경우 이미 secondary Geo 사이트에서 작동해야 합니다.

그러나 메인 및 CI PostgreSQL 데이터베이스 외부에 저장된 새로운 유형의 데이터를 도입하는 경우에는 이 데이터가 Geo에 의해 복제되고 확인되어야 합니다. 이는 고객이 재해 복구를 위해 보조 사이트를 신뢰할 수 있어야 하기 때문입니다.

다음 하위 섹션에서 필요한 작업을 확인하고, 필요한 경우 어떻게 진행해야 하는지에 대해 설명합니다. 궁금한 사항이 있으면 Geo 팀에 문의하세요.

사용자의 고유한 기능과 비교하려면 지원되는 Geo 데이터 유형을 참조하세요. Geo가 복제하고 확인하는 데이터 유형의 상세하고 최신 목록이 있습니다.

Git 저장소

Git 저장소를 백업하는 기능을 추가하는 경우 Geo 지원을 추가해야 합니다. Geo 자체 서비스 프레임워크의 저장소 복제 전략을 참조하세요.

Geo 새 블롭 유형 복제 템플릿을 기반으로 이슈를 생성하고 가이드라인에 따릅니다.

블롭

CarrierWave::Uploader::Base의 서븁클래스를 추가하면 Geo가 블롭이라고 하는 것을 추가하는 것입니다. 특히 일반적으로 권장되는 AttachmentUploader를 서브클래스화하는 경우 데이터가 이미 Geo 지원되어 추가 작업이 필요하지 않습니다. 이는 AttachmentUploaderuploads 테이블을 사용하여 Upload 모델의 블롭을 추적하고 Geo 지원이 이미 구현되어 있기 때문입니다.

만약 당신의 블롭이 GitLab.com 규모에서 백만 개의 행을 기대하기 때문에 새 테이블에서 추적된다면 Geo 지원을 추가해야 합니다. Geo 자체 서비스 프레임워크의 블롭 복제 전략을 참조하세요.

Geo는 Uploader가 해당 Replicator가 없는 경우에 실패하는 특성을 감지합니다.

Geo 새 Git 저장소 유형 복제 템플릿을 기반으로 이슈를 생성하고 가이드라인을 따르세요.

둘 이상의 유형 데이터가 있는 기능

새로운 복합 기능이 여러 종류의 데이터를 지원하는 경우, 예를 들어 Git 저장소와 블롭을 지원한다면 각 데이터 유형을 별도로 고려할 수 있습니다.

예를 들어 디자인을 살펴보면 각 이슈에는 많은 LFS 객체를 포함할 수 있는 Git 저장소가 있고, 각 LFS 객체에는 자동으로 생성된 썸네일이 있을 수 있습니다.

  • LFS 객체는 이미 Geo에서 지원되고 있기 때문에 Geo에 특화된 작업이 필요하지 않았습니다.
  • 썸네일의 구현은 이미 Upload 모델을 재사용하고 있기 때문에 Geo에 특화된 작업이 필요하지 않았습니다.
  • 디자인 Git 저장소는 본질적으로 Geo에서 지원되지 않았기 때문에 작업이 필요했습니다.

또 다른 예로 의존성 프록시DependencyProxy::BlobDependencyProxy::Manifest의 두 가지 유형의 블롭을 백업하므로 서로 독립적으로 각 유형에 Geo 자체 서비스 프레임워크의 블롭 복제 전략을 사용할 수 있습니다.

기타 데이터 유형

새로운 기능이 Git 저장소, 블롭 또는 그 둘의 조합이 아닌 새로운 데이터 유형을 도입하는 경우, Geo 팀에 문의하여 어떻게 처리할지 상의해야 합니다.

예를 들어 컨테이너 레지스트리 데이터는 위의 카테고리에 쉽게 적합하지 않습니다. 레지스트리 서비스가 소유한 데이터로, GitLab은 레지스트리 서비스의 API와 상호 작용합니다. 따라서 컨테이너 레지스트리의 Geo 지원에는 일회성 접근 방식이 필요합니다. 그럼에도 불구하고 Geo 자체 서비스 프레임워크의 많은 그루 코드를 재사용할 수 있습니다.

커뮤니케이션 채널의 변천사

첫 번째 반복 이후 커뮤니케이션 채널이 변경되었습니다. 새로운 구현 방법으로 이동한 결정 및 그 이유를 확인할 수 있습니다.

사용자 정의 코드 (GitLab 8.6 및 이전)

GitLab 8.6 이전 버전에서는 사이트에서 보조 사이트로의 알림을 처리하기 위해 사용자 정의 코드를 사용했습니다.

시스템 후크 (GitLab 8.7에서 9.5까지)

나중에, 사용자 정의 코드에서 벗어나 시스템 후크를 사용하기로 결정되었습니다. 더 많은 사용자가 사용하고 있어서 이 통신 계층에 대한 개선 사항이 많은 이득을 얻을 것으로 예상되었습니다.

우리 API 코드(Grape)에는 특정 내부 엔드포인트가 있습니다. 이 엔드포인트는 시스템 후크로부터의 모든 요청을 받습니다: /api/v4/geo/receive_events.

우리는 각 이벤트를 event_name 필드로 전환 및 필터링합니다.

Geo 로그 커서 (GitLab 10.0 이상)

GitLab 10.0 및 이후 버전에서는 시스템 웹훅은 더 이상 사용되지 않고, Geo 로그 커서가 대신 사용됩니다. 로그 커서는 Geo::EventLog 행을 탐색하여 마지막으로 로그를 확인한 이후에 변경 사항이 있는지 확인하고, 저장소 업데이트, 삭제, 변경 및 이름 바꾸기를 처리합니다.

이 테이블은 복제된 데이터베이스에 있습니다. 이전 방법보다 이 방법에는 두 가지 이점이 있습니다:

  • 복제가 동기화되며 이벤트의 순서를 보존합니다.
  • 이벤트의 복제가 데이터베이스의 변경과 동시에 발생합니다.

Self-service 프레임워크

작업 중인 리소스를 쉽게 Geo 복제하려면 셀프 서비스 프레임워크를 확인하세요.

Geo 개발 워크플로우

GET:Geo 파이프라인

성공적으로 e2e:package-and-test-ee 파이프라인을 트리거한 후, GET:Geo 작업을 수동으로 트리거할 수 있습니다:

  1. GitLab 프로젝트에서 병합 요청의 파이프라인 탭을 선택합니다.
  2. 최신 파이프라인에서 단계: qa 단계를 선택하여 관련 작업을 확장하고 나열합니다.
  3. 병합 요청에 해당하는 Omnibus GitLab Mirror 파이프라인을 보기 위해 trigger-omnibus를 선택합니다.
  4. GET:Geo 작업을 trigger-qa 단계 아래에서 찾을 수 있고 트리거할 수 있습니다.

이 파이프라인은 GET을 사용하여 1k Geo 설치를 실행하고, 인스턴스에서 gitlab-qa Geo 시나리오를 실행합니다. Geo 기능을 작업할 때, 트리거된 GET:Geo 파이프라인에서 qa-geo 작업이 통과되었는지 확인하는 것이 좋은 아이디어입니다.

인스턴스의 프로비저닝 및 해제를 제어하는 파이프라인은 GitLab Environment Toolkit Configs의 Geo subproject에 포함되어 있습니다.

새로운 기능을 추가할 때는 동작을 확인하기 위한 새로운 테스트를 추가하는 것을 고려하세요. 단계에 대해서는 QA 문서를 참조하세요.

아키텍처

이 파이프라인은 여러 다른 프로젝트 간의 상호작용을 포함합니다:

  • GitLab - 이 프로젝트의 병합 요청에서 e2e:package-and-test-ee 작업이 시작됩니다.
  • omnibus-gitlab - 트리거된 병합 요청 파이프라인에서 변경 사항을 포함하는 관련 아티팩트를 빌드합니다.
  • GET-Configs/Geo - 평가할 수 있는 짧은 기간 동안 사용될 수 있는 Geo 설치의 수명주기를 조정합니다.
  • GET - Geo 설치를 생성하고 제거하는 데 필요한 로직을 포함합니다. GET-Configs/Geo에서 사용됩니다.
  • gitlab-qa - GitLab 인스턴스에 대해 자동화된 테스트를 실행하는 도구.