시스템 유지보수

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

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

  • Git 객체 및 리비전 압축.
  • 도달할 수 없는 객체 제거.
  • Lock 파일과 같은 낡은 데이터 제거.
  • 성능을 향상시켜주는 데이터 구조 유지.
  • 포크 전체에 걸쳐 객체 이중화를 향상시키기 위한 객체 풀 업데이트.

경고: GitLab이 제어하는 Git 저장소에서 Git 명령을 수동으로 실행하지 마십시오. 이렇게 하면 저장소가 손상되고 데이터가 손실될 수 있습니다.

유지보수 전략

Gitaly는 Git 저장소에서 두 가지 방식으로 유지보수 작업을 수행할 수 있습니다:

  • Eager housekeeping는 저장소의 상태에 관계없이 특정 유지보수 작업을 실행합니다.
  • Heuristical housekeeping는 저장소의 상태에 따라 유지보수 작업을 실행하는 휴리스틱을 기반으로 합니다.

즉시 유지보수

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

즉시 유지보수 전략은 GitLab 애플리케이션에서 제어됩니다. 유지보수 작업이 실행된 트리거에 따라 GitLab은 Gitaly에게 특정 유지보수 작업을 수행하도록 요청합니다. 결과적으로, 이 전략은 저장소에 최적화된 상태에서도 Gitaly가 특정 유지보수 작업을 수행하도록 하므로 대규모 저장소에서 유지보수 작업이 지연될 수 있습니다.

휴리스틱 유지보수

  • GitLab 14.9에서 소개, 기본적으로 활성화된 optimized_housekeeping 플래그를 가진 수동 트리거 및 푸시 기반 트리거에 대해 사용됨.
  • GitLab 14.10에서 GitLab.com에서 활성화.
  • GitLab 15.8에서 일반적으로 사용 가능. 기능 플래그 optimized_housekeeping가 제거됨.

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

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

  • 느슨하고 낡은 객체의 수.
  • 이미 압축된 객체가 포함된 팩 파일의 수.
  • 느슨한 참조의 수.
  • 커밋 그래프의 존재.

분석된 데이터 구조 중 어느 것이 최적화되어야 하는지를 결정하는 것은 저장소의 크기에 따라 결정됩니다:

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

이렇게 함으로써 Gitaly는 해당 데이터 구조를 최적화하는 데 걸리는 시간이 커질수록 더 많은 시간을 소비하기 때문에 큰 모노리포(트래픽이 많이 발생하는)에서 특히 중요합니다. 이를 빈번하게 최적화하는 것을 피하기 위해 이러한 조치를 취합니다.

Gitaly에서 저장소를 최적화하도록 요청하는 빈도를 변경할 수 있습니다.

  1. 왼쪽 사이드바에서 하단에서 Admin을 선택합니다.
  2. 설정 > 저장소를 선택합니다.
  3. 저장소 유지보수를 확장합니다.
  4. 유지보수 섹션에서 유지보수 옵션을 구성합니다.
  5. 변경 사항 저장을 선택합니다.
  • 자동 저장소 유지보수 활성화: 정기적으로 Gitaly에게 저장소 최적화를 실행하도록 요청합니다. 설정을 오랫동안 비활성화하는 경우 GitLab 서버에서의 Git 저장소 액세스가 느려지고 저장소가 더 많은 디스크 공간을 사용합니다.
  • 저장소 최적화 기간: Gitaly에게 저장소를 최적화하도록 요청하는 Git 푸시 수.

유지보수 작업 실행

GitLab이 유지보수 작업을 실행하는 여러 가지 방법이 있습니다:

  • 프로젝트 관리자는 저장소에 대해 수동으로 트리거하여 유지보수 작업을 실행할 수 있습니다.
  • GitLab은 일정 수의 Git 푸시 후에 자동으로 유지보수 작업을 예약할 수 있습니다.
  • 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는 매일 정오 12:00에 10분 동안 백그라운드 저장소 유지 관리를 수행합니다.

Gitaly 설정에서 이 기본값을 변경할 수 있습니다.

Gitaly Cluster가 있는 환경의 경우, 예약된 정기 구룹청소 시작 시간은 Gitaly 노드 전체에 걸쳐 비교적 고르게 분산되어야 하므로 여러 노드에서 동시에 실행되지 않아야 합니다.

예약된 구룹청소 실행이 지정된 지속 시간에 도달하면 실행 중인 작업이 원활하게 취소됩니다. 후속 예약된 구룹청소 실행에서 Gitaly는 저장소 목록을 임의로 섞어 처리합니다.

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

직접 컴파일(소스)
[daily_maintenance]
start_hour = 23
start_minute = 00
duration = 1h
storages = ["default"]

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

[daily_maintenance]
disabled = true
리눅스 패키지(옴니버스)
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의 대체 메커니즘을 통해 새로운 오브젝트 풀에 연결합니다.
  3. 저장소를 재패킹하여 오브젝트 풀의 오브젝트를 사용하게 합니다. 따라서 저장소는 오브젝트의 자체 사본을 삭제할 수 있습니다.

이 저장소의 모든 포크는 이제 오브젝트 풀에 대한 링크를 가지고 있으므로 기본 저장소에서 벗어나는 오브젝트만 유지하면 됩니다.

GitLab은 오브젝트 풀에서 특별한 구룹청소 작업을 수행해야 합니다:

  • Gitaly는 오브젝트 풀에서 도달할 수 없는 오브젝트를 어느 포크가 사용할지 모르기 때문에 삭제해서는 안됩니다.
  • Gitaly는 동일한 이유로 항상 도달 가능한 모든 오브젝트를 유지해야 합니다. 따라서 오브젝트 풀은 삭제되지 않도록 도달할 수 없는 “둥둥 떠다니는” 오브젝트에 대한 참조를 유지합니다.
  • GitLab은 기본 저장소에 추가된 새로운 오브젝트를 정기적으로 오브젝트 풀에 동기화해야 합니다. 그렇지 않으면 오브젝트 풀은 계속해서 오브젝트 중복을 증가시킬 뿐입니다.

이러한 구룹청소 작업은 표준 Git 저장소에 대해 실행하는 정기적인 구룹청소 작업과 동시에 모든 이러한 특별한 작업을 처리하는 전문화된 FetchIntoObjectPool RPC에 의해 수행됩니다.

오브젝트 풀은 주요 멤버가 가비지 수집될 때 자동으로 최적화됩니다. 따라서 프로젝트의 Git GC 기간을 사용하여 케디언스를 구성할 수 있습니다.

만약 레일즈 콘솔에서 RPC를 수동으로 호출해야 하는 경우 project.pool_repository.object_pool.fetch를 호출할 수 있습니다. 이 것은 잠재적으로 오랜 시간 동안 실행되는 작업이지만 Gitaly는 약 8시간 후에 타임아웃됩니다.