Uploads 개발 지침

업로드는 많은 GitLab 기능의 중요한 부분입니다. GitLab이 업로드를 처리하는 주요 매커니즘에 대한 개요를 제공하기 위해 이 페이지가 제공됩니다.

GitLab 업로드는 기능별로 구성됩니다. 업로드를 포함하는 모든 기능은 동일한 구성 옵션을 제공하지만 서로 독립적으로 구성할 수 있습니다. 예를 들어, Git LFS 업로드는 CI/CD 빌드 아티팩트 업로드와 독립적으로 구성할 수 있지만, 두 경우 모두 동일한 설정 키 집합을 제공합니다. 이러한 설정은 업로드가 어떻게 처리되는지를 규제하며, 이는 성능과 확장성에 지대한 영향을 미칠 수 있습니다.

이 페이지는 이러한 파일이 어떻게 처리되는지 결정하는 데 중요한 업로드 설정을 요약합니다. 그런 다음 다음 섹션에서 각 매커니즘을 더 자세히 설명합니다.

업로드 설정이 업로드 흐름을 어떻게 구동시키는가

더 자세한 개별 업로드 전략을 살펴보기 전에,이러한 전략 각각에 어떤 업로드 설정이 매핑되는지에 대한 고수준 분석을 살펴봅시다.

업로드 설정 자체는 업로드 관리에서 문서화되어 있습니다. 여기서는 이러한 설정이 GitLab 업로드 로직의 내부를 어떻게 구동시키는 지에 중점을 둡니다.

최상위 수준에서 업로드 된 파일에 대한 두 가지 대상을 구별합니다:

  • 로컬 저장소 - 파일은 웹 서버 노드에 연결된 볼륨에 저장됩니다.
  • 객체 저장소 - 파일은 원격 객체 저장소 버킷에 저장됩니다.

이 표에서 x.y.zgitlab.yml을 통해 취해진 경로를 지정합니다:

설정 동작
<기능>.object_store.enabled false 파일은 <기능>.storage_path에 로컬로 저장됩니다.
<기능>.object_store.enabled true 파일은 <기능>.object_store.remote_directory에 원격으로 저장됩니다.

객체 저장소를 사용할 때, 관리자는 해당 파일이 해당 버킷으로 어떻게 이동하는지 제어할 수 있습니다. 이 이동은 다음 중 하나의 방법으로 발생할 수 있습니다:

개별 Sidekiq 워커도 객체 저장소에 파일을 저장할 수 있으며, 이는 여기서 다루지 않습니다.

마지막으로, Workhorse는 대부분의 사용자 시작 업로드를 업로드 버퍼링 메커니즘을 사용하여 지연 처리된 작업을 레일즈 컨트롤러에서 유지하는 데 도움을 줍니다. 이 메커니즘은 Workhorse 지원 업로드에 설명되어 있으며, 이는 우리가 이전에 논의한 것과 대조적으로 직교적으로 실행됩니다.

이제 각 경우를 자세히 살펴봅니다.

로컬 저장소

로컬 저장소는 업로드의 가장 간단한 경로입니다. 이것은 GitLab이 초기에 업로드를 처리한 방식이었습니다. 이것은 저장소 볼륨(디스크 또는 네트워크에 연결된 저장소)이 레일즈 애플리케이션에서storage_path에 접근 가능하다고 가정합니다. 이 파일 경로는 레일즈 루트 디렉토리를 기준으로 상대적이며, 다른 업로드 설정과 마찬가지로 기능별로 구성할 수 있습니다.

클라이언트가 파일 업로드를 보낼 때, Workhorse는 먼저 파일을 디스크에 버퍼링하고 이 메커니즘은 Workhorse 지원 업로드에서 더 자세히 설명되어 있습니다. 요청이 레일즈 어플리케이션에 도달하면 파일은 이미 로컬 저장소에 존재하므로 레일즈는 트랜잭션을 완료하기 위해 지정된 디렉토리로 이동하기만 하면 됩니다.

로컬 저장소는 클라우드 기반 GitLab (CNG) 설치에는 사용할 수 없습니다. 따라서 GitLab SaaS에도 사용되지 않습니다.

객체 저장소

수평적으로 확장 가능한 저장소를 제공하기 위해 다음과 같은 객체 저장소 제공 업체를 사용해야 합니다:

  • Amazon AWS.
  • Google Cloud Storage (GCS).
  • Azure Cloud Storage.

객체 저장소를 사용하면 두 가지 주요 이점을 제공합니다:

  • 보다 많은 저장 용량 추가의 용이성: 클라우드 제공 업체가 자동으로 수행합니다.
  • GitLab 설치의 수평적 확장 가능성 활성화: 여러 GitLab 어플리케이션 서버가 동일한 데이터에 액세스할 수 있습니다.

GitLab SaaS를 포함한 CNG 설치는 항상 객체 저장소를 사용합니다 (GitLab SaaS의 경우 GCS).

원격 객체 저장소로 업로드하는 것의 어려움은 GitLab에서 객체 저장소 제공자로의 아웃바운드 HTTP 요청이 포함된다는 것입니다. 앞에서 언급했듯이,이 HTTP 요청이 전송되는 방법에는 세 가지 다른 전략이 있습니다.

레일즈 컨트롤러 업로드

직접 업로드할 수 없을 때, 레일즈는 컨트롤러 create 액션의 일부로 파일을 객체 저장소에 업로드합니다. 책임을 지는 레일즈 컨트롤러는 업로드하는 파일의 종류에 따라 다릅니다.

레일즈 컨트롤러 업로드는 로컬 저장소로 업로드하는 것과 매우 유사합니다. 주요 차이점: 레일즈는 객체 저장소로 HTTP 요청을 보내야 한다는 것입니다. 이 작업은 CarrierWave Fog 업로더를 통해 이루어집니다.

로컬 저장소와 마찬가지로,이 전략은 Workhorse 지원을 통해 유용한 부분을 레일즈와 Ruby의 많은 I/O 작업을 처리하는 것을 돕습니다. 직접 업로드는 이 일부 비용이 높은 HTTP PUT 요청을 Puma 밖의 객체 저장소로 유지하기 때문에 이 작업을 더 잘 수행합니다.

이 전략은 작은 파일 업로드에 적합하며, Puma의 60초 요청 제한이 적용됩니다.

직접 업로드

SaaS와 같은 CNG 설치에서 대규모 파일을 객체 스토리지로 이동시키는 권장 방법입니다.

직접 업로드가 활성화되면 Workhorse는 다음 작업을 수행합니다.

  1. 요청을 Rails로 승인합니다.
  2. 객체 저장소 자체와 연결하여 파일을 임시 위치로 전송합니다.
  3. 전송이 완료되면 Workhorse가 요청을 Rails로 최종화합니다. Rails는 객체 저장소 복사 작업을 수행하여 파일을 최종 위치에 넣습니다.
  4. 객체 저장소의 임시 파일을 삭제하여 업로드를 완료합니다.

이 전략은 Workhorse assisted uploads의 다른 형태입니다. Workhorse와 Puma 양쪽에서 접근할 수 있는 공유 저장소에 의존하지 않습니다.

기존 업로드 전략 중에서 직접 업로드가 대용량(기가바이트) 업로드를 가장 잘 처리할 수 있습니다. 그러나 Puma가 여전히 객체 저장소 복사 작업을 수행하기 때문에 업로드 크기에 비례하여 시간이 소요되는 가능성이 있어 Puma 타임아웃이 발생할 수 있습니다.

Workhorse 도움을 받는 업로드

대부분의 업로드는 어떤 식으로든지 Workhorse의 도움을 받습니다.

  • 종종, Workhorse는 업로드를 임시 파일로 버퍼링합니다. Workhorse는 요청에 메타데이터를 추가하여 Puma에게 임시 파일의 이름과 위치를 알려줍니다. 이는 Workhorse와 Puma 간에 공유된 임시 저장소를 필요로 합니다. 모든 GitLab 설치(포함 CNG)에는 이러한 공유 임시 저장소가 있습니다.
  • Workhorse가 때로는 파일을 사전 처리합니다. 예를 들어 CI 아티팩트 업로드의 경우, Workhorse가 ZIP 파일 내용의 별도 색인을 만듭니다. 이를 Workhorse에서 수행함으로써 Puma 요청 제한 시간을 우회할 수 있습니다. Sidekiq 백그라운드 처리와 비교하여 사용자가 파일을 수락했지만 아직 처리하지 않은 중간 상태를 볼 수 없는 장점이 있습니다.
  • 직접 업로드를 통해 Workhorse가 파일 사전 처리와 객체 스토리지로 업로드를 모두 수행할 수 있습니다. 대용량 파일을 객체 스토리지에 업로드하는 데는 시간이 걸리며, 이를 Workhorse에서 수행함으로써 Puma 요청 제한 시간을 피할 수 있습니다.