Housekeeping

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

GitLab은 Git 리포지토리의 관리 작업을 지원하고 자동화하여 가능한 효율적으로 제공될 수 있도록 합니다. 관리 작업에는 다음이 포함됩니다:

  • Git 객체 및 리비전 압축.
  • 도달할 수 없는 객체 제거.
  • 잠긴 파일과 같은 오래된 데이터 제거.
  • 성능을 향상시키는 데이터 구조 유지.
  • 지점을 통해 객체의 중복을 개선하기 위해 객체 풀 업데이트.
caution
GitLab에서 제어하는 Git 리포지토리에서 관리 작업을 수행하기 위해 Git 명령을 수동으로 실행하지 마십시오. 이렇게 하면 리포지토리가 손상되고 데이터가 손실될 수 있습니다.

Housekeeping 전략

Gitaly는 Git 리포지토리에서 두 가지 방법으로 관리 작업을 수행할 수 있습니다:

  • 적극적 관리는 저장소의 상태와 관계없이 특정 관리 작업을 수행합니다.
  • 휴리스틱 관리는 저장소 상태에 따라 어떤 관리 작업이 실행되어야 하는지를 결정하는 휴리스틱 세트를 기반으로 관리 작업을 수행합니다.

적극적 관리

“적극적” 관리 전략은 저장소의 상태와 관계없이 관리 작업을 실행합니다. 이것은 수동 트리거와 푸시 기반 트리거에서 사용되는 기본 전략입니다.

적극적 관리 전략은 GitLab 응용 프로그램에서 제어됩니다. 관리 작업을 실행하도록 유발한 트리거에 따라 GitLab이 Gitaly에게 특정 관리 작업을 수행하도록 요청합니다. 결과적으로 이 전략은 큰 리포지토리에서 관리 작업을 실행하는 데 시간이 오래 걸릴 수 있기 때문에 리포지토리가 최적 상태인 경우에도 이러한 작업을 수행합니다.

휴리스틱 관리

  • GitLab 14.9에서 수동 트리거 및 푸시 기반 트리거를 위해 optimized_housekeeping이라는 플래그로 도입되었습니다. 기본적으로 활성화됨.
  • GitLab 14.10에서 GitLab.com에서 활성화됨.
  • GitLab 15.8에서 일반적으로 사용 가능해짐. optimized_housekeeping 플래그가 제거됨.

휴리스틱(또는 “기회주의적”) 관리 전략은 저장소의 상태를 분석하고 하나 이상의 데이터 구조가 충분히 최적화되지 않은 경우에만 관리 작업을 실행합니다. 이는 예약 관리에서 사용하는 전략입니다.

휴리스틱 관리는 다음 정보를 사용하여 실행해야 할 작업을 결정합니다:

  • 잡히지 않는 루즈 및 오래된 객체의 수.
  • 이미 압축된 객체를 포함하는 팩 파일의 수.
  • 루즈 참조의 수.
  • 커밋 그래프의 존재.

분석된 데이터 구조 중 어떤 것들을 최적화해야 하는지에 대한 결정은 리포지토리의 크기에 따라 달라집니다:

  • 객체는 전체 객체의 총 크기가 클수록 자주 다시 패킹됩니다.
  • 참조는 총 참조가 많을수록 자주 다시 패킹됩니다.

Gitaly는 이것을 수행하여 이러한 데이터 구조를 최적화하는 데 드는 시간이 증가함을 상쇄시킵니다. 특히 많은 트래픽을 받는 큰 모노 리포지토리에서 이를 너무 자주 최적화하지 않도록하는 것이 중요합니다.

Gitaly가 저장소를 최적화할 때 얼마나 자주 요청할지를 변경할 수 있습니다.

  1. 왼쪽 사이드바에서 아래쪽에 있는 관리 영역을 선택합니다.
  2. 설정 > 리포지토리를 선택합니다.
  3. 리포지토리 유지 관리를 확장합니다.
  4. Housekeeping 섹션에서 관리 옵션을 구성합니다.
  5. 변경 사항 저장을 선택합니다.
  • 자동 리포지토리 관리 활성화: 정기적으로 Gitaly에게 저장소 최적화를 실행하도록 요청합니다. 이 설정을 오랫동안 비활성화하면 GitLab 서버에서 Git 리포지토리 액세스가 더 느려지고 리포지토리가 더 많은 디스크 공간을 사용합니다.
  • 리포지토리 최적화 기간: Gitaly에게 저장소 최적화를 요청하는 Git 푸시 횟수. 번역이 필요한 도구를 제공하기 위해 이 설정을 오랫동안 비활성화하면 GitLab 서버에서 Git 리포지토리 액세스가 더 느려지고 리포지토리가 더 많은 디스크 공간을 사용합니다.

관리 작업 실행

GitLab이 관리 작업을 실행하는 다양한 방법이 있습니다:

  • 프로젝트 관리자는 리포지토리 수동 트리거를 실행할 수 있습니다.
  • GitLab은 일정 이후에 자동으로 관리 작업을 예약할 수 있습니다.
  • GitLab은 지정된 시간 프레임 내에 모든 저장소에 대해 관리 작업을 실행하는 작업을 예약할 수 있습니다.

수동 트리거

저장소 관리자는 리포지토리에서 관리 작업을 수동으로 실행할 수 있습니다. 일반적으로 GitLab이 자동으로 관리 작업을 실행하도록 되어 있기 때문에 이 기능을 사용할 필요는 없습니다. 수동 트리거는 다음과 같은 경우에 유용할 수 있습니다:

  • 리포지토리가 관리 작업이 필요한 것으로 알려져 있을 때.
  • 관리 작업이 자동 푸시 기반 예약이 비활성화된 경우.

수동으로 관리 작업을 트리거하려면:

  1. 왼쪽 사이드바에서 검색 또는 이동을 선택하고 프로젝트를 찾습니다.
  2. 설정 > 일반을 선택합니다.
  3. 고급을 확장합니다.
  4. 관리 작업 실행을 선택합니다.

이 작업은 프로젝트 리포지토리에 대해 비동기식 백그라운드 작업자를 시작합니다. 이 작업자는 Gitaly에게 여러 최적화를 실행하도록 요청합니다.

관리 작업은 또한 프로젝트의 참조되지 않는 LFS 파일을 제거하여 프로젝트에서 200푸시마다 저장 공간을 확보합니다.

이륵이 끊긴 객체 정리

예정된 하우스키퍼링의 일환으로 이륵이 끊긴 객체가 정리됩니다. 그러나 수동 정리를 직접 트리거할 수도 있습니다. 예를 들어, 민감한 정보가 포함된 커밋을 제거하는 경우입니다. 하우스키퍼링을 트리거하면 이륵이 끊긴 객체가 2주의 유예 기간을 가지고 정리됩니다. 이륵이 끊긴 객체를 수동으로 정리를 트리거할 경우, 유예 기간이 30분으로 줄어듭니다.

경고: git push와 같은 동시 프로세스가 객체를 생성했지만 아직 객체에 대한 참조를 만들지 않은 경우에, 객체가 삭제된 후에 참조가 추가된다면 저장소가 손상될 수 있습니다. 유예 기간이 존재하는 이유는 이러한 경주 조건이 발생할 가능성을 줄이기 위해서입니다. 예를 들어, 때로는 매우 느린 연결에서 자주 큰 객체를 많이 푸시하는 경우에, 이륵이 끊긴 객체를 정리하는 것에 따른 위험이 회사 내부의 성능 좋은 연결로만 접근할 수 있는 기업 환경보다 훨씬 높습니다. 이 옵션을 사용할 때 프로젝트 사용 프로파일을 고려하고 조용한 기간을 선택하세요.

이륵이 끊긴 객체를 수동으로 정리하는 방법:

  1. 왼쪽 사이드바에서 검색 또는 이동을 선택하고 프로젝트를 찾습니다.
  2. 설정 > 일반을 선택합니다.
  3. 고급을 확장합니다.
  4. 하우스키퍼링 실행을 선택합니다.
  5. 작업이 완료될 때까지 30분 기다립니다.
  6. 하우스키퍼링 실행을 선택한 페이지로 돌아가서 이륵이 끊긴 객체 정리를 선택합니다.

예정된 하우스키퍼링

GitLab은 프로젝트의 푸시 수에 기반하여 자동으로 하우스키퍼링 작업을 수행하지만, 전혀 푸시를 받지 않는 저장소를 유지하지 않습니다. 결과적으로 활성되지 않거나 읽기 전용 요청만 받는 저장소는 하우스키퍼링 전략의 향상을 누리지 못할 수 있습니다.

관리자는 이러한 상황을 해결하기 위해 모든 저장소에서 사용자 정의 가능한 간격으로 하우스키퍼링을 수행하는 백그라운드 작업을 활성화시킬 수 있습니다. 이 백그라운드 작업은 Gitaly 노드에 의해 호스팅된 모든 저장소를 임의의 순서로 처리하고 즉시 하우스키퍼링 작업을 수행합니다. Gitaly 노드는 구성된 간격보다 길게 걸릴 경우 저장소 처리를 중지합니다.

예정된 하우스키퍼링 구성

Git 저장소의 백그라운드 유지 관리는 Gitaly에서 구성됩니다. 기본적으로 Gitaly는 매일 정오에 10분 동안의 백그라운드 저장소 유지 관리를 수행합니다.

이 기본값은 Gitaly 구성에서 변경할 수 있습니다.

Gitaly 클러스터 환경에서는 예정된 하우스키퍼링 시작 시간을 Gitaly 노드 간에 겹치지 않도록 순차적으로 할 수 있습니다.

예정된 하우스키퍼링 작업이 구성된 지속시간에 도달하면 실행 중인 작업이 정상적으로 취소됩니다. 다음에 예정된 하우스키퍼링 실행에서는 Gitaly가 저장소 목록을 임의로 섞어 처리합니다.

다음 스니펫은 default 저장소에 대해 23:00에 1시간 동안 매일 백그라운드 저장소 유지 관리를 활성화합니다:

컴파일 자체 (소스)
[일일_유지관리]
시작_시간 = 23
시작_분 = 00
지속시간 = 1시간
저장소 = ["default"]

다음 스니펫은 백그라운드 저장소 유지 관리를 완전히 비활성화합니다:

[일일_유지관리]
비활성화됨 = true
Linux 패키지 (Omnibus)
gitaly['configuration'] = {
  daily_maintenance: {
    disabled: false,
    start_hour: 23,
    start_minute: 00,
    duration: '1h',
    storages: ['default'],
  },
}

다음 스니펫은 백그라운드 저장소 유지 관리를 완전히 비활성화합니다:

gitaly['configuration'] = {
  daily_maintenance: {
    disabled: true,
  },
}

예정된 하우스키퍼링이 실행되면 Gitaly 로그에 다음 항목을 확인할 수 있습니다:

# 예정된 하우스키퍼링이 시작될 
{"level":"info","msg":"maintenance: daily scheduled","pid":197260,"scheduled":"2023-09-27T13:10:00+13:00","time":"2023-09-27T00:08:31.624Z"}

# 예정된 하우스키퍼링이 완료될 
{"actual_duration":321181874818,"error":null,"level":"info","max_duration":"1h0m0s","msg":"maintenance: daily completed","pid":197260,"time":"2023-09-27T00:15:21.182Z"}

actual_duration (나노초)은 예정된 유지 관리가 실행되는 데 걸린 시간을 나타냅니다. 위의 예에서 예정된 하우스키퍼링은 5분 정도 소요되어 완료되었습니다.

객체 풀 저장소

객체 풀 저장소는 리포지토리의 포크간에 다른 방식으로 객체를 중복 저장할 수 있도록 GitLab에서 사용됩니다. 첫 번째 포크를 만들 때 다음과 같은 작업이 수행됩니다:

  1. 리포지토리의 모든 객체를 포함하는 객체 풀 저장소를 생성합니다.
  2. 해당 리포지토리를 새로운 객체 풀에 연결합니다(Git의 alternates 메커니즘을 통해).
  3. 리포지토리를 다시 패킹하여 객체 풀의 객체를 사용하도록 합니다. 따라서 리포지토리는 고유의 객체 복사본을 삭제할 수 있습니다.

이러한 리포지토리의 포크들은 이제 객체 풀에 링크되어 주요 리포지토리와 다른 객체만 유지하면 됩니다.

GitLab은 객체 풀에서 특별한 하우스키퍼링 작업을 수행해야 합니다:

  • Gitaly는 객체 풀에서 이륵이 끊긴 객체를 삭제할 수 없습니다. 왜냐하면 객체 풀에 연결된 포크 중 어느 것이든 사용할 수 있기 때문입니다.
  • Gitaly는 동일한 이유로 모든 이륵이 끊긴 객체에 대한 참조를 유지해야 합니다. 따라서 객체 풀은 삭제되지 않도록 이륵이 끊긴 “둥둥 떠다니는” 객체에 대한 참조를 유지합니다.
  • GitLab은 주요 리포지토리에 추가된 새 객체를 정기적으로 객체 풀에 업데이트해야 합니다. 그렇지 않으면 객체 풀은 점점 효율적이지 못해집니다.

이러한 하우스키퍼링 작업은 전용 FetchIntoObjectPool RPC에 의해 수행됩니다. 이 RPC는 일반적인 Git 리포지토리에 대해 실행하는 정기적인 하우스키퍼링 작업 뿐만 아니라 이러한 특별한 작업을 수행합니다.

객체 풀은 주요 멤버가 쓰레기 수집되는 경우에 자동으로 최적화됩니다. 따라서 프로젝트에서 동일한 Git GC 주기를 사용하여 이러한 케이던스를 구성할 수 있습니다.

만약 Rails 콘솔에서 RPC를 수동으로 호출해야 하는 경우 project.pool_repository.object_pool.fetch를 호출할 수 있습니다. 이 작업은 시간이 오래 걸릴 수 있으나, Gitaly는 약 8시간 후에 타임아웃됩니다.