하우스키퍼링

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

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

  • Git 객체 및 리비전의 압축
  • 도달할 수 없는 객체 제거
  • Lock 파일과 같은 잔여 데이터 제거
  • 성능을 향상시키는 데이터 구조 유지
  • 포크 간 객체 중복을 개선하기 위한 객체 풀 업데이트
caution
GitLab에서 제어하는 Git 리포지터리에서 하우스키퍼링을 수행하기 위해 매뉴얼으로 Git 명령을 실행하지 마십시오. 이렇게 하면 리포지터리가 손상되고 데이터가 손실될 수 있습니다.

하우스키퍼링 전략

Gitaly는 Git 리포지터리에서 하우스키퍼링 작업을 두 가지 방법으로 수행할 수 있습니다.

  • 이저 하우스키퍼링은 리포지터리의 상태와 관계없이 특정 하우스키퍼링 작업을 실행합니다.
  • 휴리스티컬 하우스키퍼링은 리포지터리 상태에 따라 실행해야 할 하우스키퍼링 작업을 결정하는 일련의 휴리스틱에 기반하여 하우스키퍼링 작업을 실행합니다.

이저 하우스키퍼링

“이저” 하우스키퍼링 전략은 리포지터리의 상태와 관계없이 하우스키퍼링 작업을 실행합니다. 이는 매뉴얼 트리거와 push 기반 트리거가 사용하는 기본 전략입니다.

이저 하우스키퍼링 전략은 GitLab 애플리케이션에 의해 제어됩니다. 하우스키퍼링 작업을 실행시킨 트리거에 따라 GitLab은 Gitaly에게 특정 하우스키퍼링 작업을 수행하도록 요청합니다. 리포지터리가 최적화된 상태에 있더라도 Gitaly은 이러한 작업을 수행합니다. 따라서 이러한 전략은 하우스키퍼링 작업 실행이 느릴 수 있는 대규모 리포지터리에서 비효율적일 수 있습니다.

휴리스티컬 하우스키퍼링

휴리스티컬(또는 “기회주의적”) 하우스키퍼링 전략은 리포지터리 상태를 분석하고 하나 이상의 데이터 구조가 충분히 최적화되지 않은 경우에만 하우스키퍼링 작업을 실행합니다. 이는 스케줄된 하우스키퍼링에서 사용하는 전략입니다.

휴리스티컬 하우스키퍼링은 다음 정보를 사용하여 실행할 작업을 결정합니다:

  • 낡고 잔여한 객체 수
  • 이미 압축된 객체를 포함하는 팩 파일 수
  • 낡은 참조 수
  • 커밋 그래프의 존재

분석한 데이터 구조 중 어떤 것을 최적화해야 하는지 결정하는 방법은 리포지터리의 크기에 의해 결정됩니다:

  • 객체는 전체 객체 크기가 클수록 자주 다시 팩 파일로 묶입니다.
  • 참조는 총 참조 수가 많을수록 덜 자주 다시 팩 파일로 묶입니다.

Gitaly은 데이터 구조가 커질수록 최적화하는 데 더 많은 시간이 걸리기 때문에 어떤 데이터 구조의 최적화가 필요한지 결정합니다. 특히 많은 트래픽을 받는 대규모 모노리포에서 이러한 작업을 지나치게 자주 수행하지 않도록 조치를 취합니다.

Gitaly의 최적화 빈도를 변경할 수 있습니다.

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

하우스키퍼링 작업 실행

GitLab이 하우스키퍼링 작업을 실행하는 방법에는 여러 가지가 있습니다:

  • 프로젝트의 관리자는 리포지터리 하우스키퍼링 작업을 수동으로 트리거할 수 있습니다.
  • GitLab은 일정 수의 Git 푸시 후에 자동으로 하우스키퍼링 작업을 예약할 수 있습니다.
  • GitLab은 설정 가능한 시간대에 모든 리포지터리에 대해 하우스키퍼링 작업을 실행하는 작업을 예약할 수 있습니다.

매뉴얼 트리거

리포지터리의 관리자는 리포지터리에서 하우스키퍼링 작업을 수동으로 트리거할 수 있습니다. 일반적으로 GitLab은 자동으로 하우스키퍼링 작업을 실행하도록 알고 있으므로 이 기능은 필요하지 않습니다. 매뉴얼 트리거는 다음 경우에 유용합니다:

  • 리포지터리가 하우스키퍼링을 필요로 하는 경우
  • 자동 push 기반으로 하우스키퍼링 작업 예약이 비활성화된 경우

하우스키퍼링 작업을 수동으로 트리거하려면:

  1. 좌측 사이드바에서 검색 또는 이동하여 이동을 선택하고 프로젝트를 찾습니다.
  2. 설정 > 일반을 선택합니다.
  3. 고급을 확장합니다.
  4. 하우스키퍼링 실행을 선택합니다.

이려면 프로젝트 리포지터리에 대해 비동기 백그라운드 워커를 시작합니다. 백그라운드 워커는 Gitaly에게 최적화 작업을 수행하도록 요청합니다.

하우스키퍼링은 또한 프로젝트 리포지터리에서 매 200번의 푸시 후에 참조되지 않은 LFS 파일을 제거하여 프로젝트의 저장 공간을 확보합니다.

도달할 수 없는 객체 제거

도달할 수 없는 객체는 스케줄된 하우스키퍼링의 일부로 제거됩니다. 그러나 매뉴얼으로 또한 가지고 막다. 예를 들어, 민감한 정보가 포함된 커밋을 제거합니다. 하우스키퍼링을 트리거하면 도달할 수 없는 객체가 2주의 유예 기간으로 제거됩니다. 도달할 수 없는 객체의 매뉴얼 가지고 막으면 유예 기간이 30분으로 줄어듭니다.

caution
동시 프로세스(예: git push)가 객체를 생성했지만 아직 객체에 대한 참조를 만들지 않은 경우, 객체가 삭제된 후에 참조가 추가되면 리포지터리가 손상될 수 있습니다. 유예 기간은 이러한 레이스 조건의 발생 가능성을 줄이기 위해 존재합니다. 예를 들어, 가끔 매우 느린 연결로 많은 대형 객체를 자주 푸시하는 경우 도달할 수 없는 객체를 가지고 막는 위험은 회사 내부에서만 고속 연결을 통해 액세스할 수 있는 환경보다 훨씬 더 큽니다. 이 옵션을 사용할 때는 프로젝트 사용 프로파일을 고려하고 조용한 기간을 선택하십시오.

도달할 수 없는 객체의 매뉴얼 가지고 막기를 트리거하려면:

  1. 좌측 사이드바에서 검색 또는 이동하여 이동을 선택하고 프로젝트를 찾습니다.
  2. 설정 > 일반을 선택합니다.
  3. 고급을 확장합니다.
  4. 하우스키퍼링 실행을 선택합니다.
  5. 작업이 완료되기까지 30분을 기다립니다.
  6. Run housekeeping을 선택한 페이지로 돌아가서 Prune unreachable objects를 선택합니다.

스케줄된 하우스키퍼링

GitLab은 푸시한 횟수에 따라 자동으로 하우스키퍼링 작업을 수행하지만 전혀 푸시되지 않은 리포지터리는 유지되지 않습니다. 결과적으로 활동하지 않는 리포지터리 또는 읽기 전용 요청만하는 리포지터리는 리포지터리 하우스키퍼링 전략의 개선을 이용할 수 없습니다.

관리자는 이러한 상황을 해결하기 위해 모든 리포지터리에서 일정한 간격으로 하우스키퍼링을 수행하는 백그라운드 작업을 활성화할 수 있습니다. 이 백그라운드 작업은 Gitaly 노드에 의해 호스팅되는 모든 리포지터리를 임의로 처리하고 이를 자극적으로 실행합니다. Gitaly 노드는 구성된 간격보다 긴 시간이 걸릴 경우 리포지터리 처리를 중지합니다.

스케줄된 하우스키퍼링 구성

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

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

Gitaly 클러스터 환경의 경우, 스케줄된 하우스키퍼링 시작 시간은 여러 Gitaly 노드에 걸쳐 비교적 간격을 두어 실행되지 않도록 설정할 수 있습니다.

스케줄된 하우스키퍼링 실행이 시작되면 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. 리포지터리를 새로운 객체 풀에 대체 메커니즘을 통해 연결합니다.
  3. 리포지터리를 리팩하여 객체 풀에서 객체를 사용하도록 만듭니다. 따라서 자체 객체 사본을 삭제할 수 있습니다.

이제 이 리포지터리의 어떤 포크든 객체 풀에 연결하여, 주 리포지터리와 다르게 벗어난 객체만 보유하면 됩니다.

GitLab은 객체 풀에서 특별한 유지 관리 작업을 수행해야 합니다:

  • Gitaly는 객체 풀에서 접근할 수 없는 객체를 절대로 삭제할 수 없습니다. 왜냐하면 그것들은 연결된 어떤 포크에서든 사용될 수 있기 때문입니다.
  • Gitaly는 똑같은 이유 때문에 이러한 객체들을 모두 유지해야 합니다. 따라서 객체 풀은 삭제되지 않도록 도르래진 참조를 유지합니다.
  • GitLab은 주 리포지터리에 추가된 새로운 객체들을 정기적으로 가져와야 합니다. 그렇지 않으면 객체 풀은 객체를 중복으로 저장하는 것이 점점 비효율적으로 됩니다.

이러한 유지 관리 작업은 특수한 FetchIntoObjectPool RPC에 의해 수행됩니다. 이 작업은 모든 이러한 특별한 작업을 처리하면서 일반 Git 리포지터리에 대해 실행하는 기본 수행 작업도 수행합니다.

객체 풀은 주 멤버가 가비지 수집될 때 자동으로 최적화됩니다. 따라서 해당 프로젝트의 Git GC 기간을 사용하여 캐딘스를 구성할 수 있습니다.

만약 Rails 콘솔에서 RPC를 매뉴얼으로 호출해야 한다면, project.pool_repository.object_pool.fetch를 호출할 수 있습니다. 이 작업은 잠재적으로 긴 시간이 걸리지만, Gitaly는 약 8시간 후에 타임아웃됩니다.