업로드 개발 지침

업로드는 많은 GitLab 기능의 필수적인 부분입니다. 이 페이지는 GitLab이 업로드를 처리하는 방법을 이해하기 위해 파일을 저장소로 전송하는 주요 메커니즘에 대한 개요를 제공합니다.

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

이 페이지는 이러한 파일이 처리되는 방식을 결정하는 데 중요한 업로드 설정을 요약합니다. 이어지는 섹션에서는 이러한 메커니즘 각각에 대해 더 자세히 설명합니다.

업로드 설정이 업로드 흐름에 미치는 영향

개별 업로드 전략을 더 자세히 살펴보기 전에, 각 업로드 설정이 이러한 전략에 어떻게 매핑되는지에 대한 높은 수준의 분류를 살펴보겠습니다.

업로드 설정 자체는 업로드 관리에서 문서화되어 있습니다.

여기에서는 이러한 설정이 GitLab 업로드 논리의 내부를 어떻게 구동하는지에 중점을 둡니다.

상위 수준에서 우리는 업로드된 파일의 두 개의 대상을 구분합니다:

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

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

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

객체 저장소를 사용할 때, 관리자는 해당 파일이 각각의 버킷으로 이동하는 방식을 제어할 수 있습니다.

이 이동은 다음 방식 중 하나로 발생할 수 있습니다:

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

마지막으로, Workhorse는 느린 작업을 Rails 컨트롤러에서 제외하기 위해 업로드 버퍼링 메커니즘을 사용하여 대부분의 사용자 주도 업로드를 지원합니다. 이 메커니즘은 Workhorse 지원 업로드에서 설명되며, 우리가 앞서 논의한 것과는 별개로 작동합니다.

이제 각 경우를 더 자세히 살펴보겠습니다.

로컬 저장소

로컬 저장소는 업로드가 취할 수 있는 가장 단순한 경로입니다. 이는 GitLab이 초기 단계에서 업로드를 처리했던 방법입니다.

이는 스토리지 볼륨(디스크나 네트워크에 연결된 스토리지와 같은)이 storage_path에서 Rails 애플리케이션에 액세스할 수 있다고 가정합니다. 이 파일 경로는 Rails 루트 디렉터리에 상대적이며, 다른 업로드 설정과 마찬가지로 기능별로 구성할 수 있습니다.

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

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

객체 저장소

수평적으로 확장 가능한 저장소를 제공하려면 Amazon AWS, Google Cloud Storage(GCS), Azure Cloud Storage와 같은 객체 저장소 공급자를 사용해야 합니다.

객체 저장소를 사용하면 두 가지 주요 이점이 있습니다:

  • 더 많은 저장 용량 추가의 용이성: 클라우드 공급자는 이를 자동으로 처리합니다.
  • GitLab 설치의 수평적 확장을 가능하게 합니다: 여러 GitLab 애플리케이션 서버가 객체 저장소에 저장된 동일한 데이터에 액세스할 수 있습니다.

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

원격 객체 저장소에 업로드하는 것은 GitLab에서 객체 저장소 공급자에게 발송되는 아웃고잉 HTTP 요청을 포함하는 도전 과제가 있습니다. 앞서 언급했듯이 이 HTTP 요청이 전송되는 방법에는 세 가지 다른 전략이 있습니다.

Rails 컨트롤러 업로드

직접 업로드가 불가능할 때, Rails는 컨트롤러 create 액션의 일환으로 파일을 객체 저장소에 업로드합니다. 어떤 컨트롤러가 책임이 있는지는 업로드된 파일 종류에 따라 다릅니다.

Rails 컨트롤러 업로드는 로컬 저장소에 업로드하는 것과 매우 유사합니다. 주요 차이점은 Rails가 객체 저장소에 HTTP 요청을 보내야 한다는 점입니다. 이는 CarrierWave Fog 업로더를 통해 발생합니다.

로컬 저장소와 마찬가지로, 이 전략은 Ruby와 Rails의 비용이 많이 드는 I/O 작업을 피하기 위해 Workhorse 지원을 활용합니다. 직접 업로드는 객체 저장소에 대한 HTTP PUT 요청을 Puma 외부에서 처리하여 이를 더 잘 수행합니다.

이 전략은 작은 파일 업로드에만 적합하며, Puma의 60초 요청 타임아웃에 영향을 받습니다.

직접 업로드

직접 업로드는 GitLab SaaS와 같은 CNG 설치에서 큰 파일을 객체 저장소로 이동하는 권장 방법입니다.

직접 업로드를 사용하도록 설정하면, Workhorse는 다음을 수행합니다:

  1. Rails와 요청을 인증합니다.
  2. 파일을 임시 위치로 전송하기 위해 객체 저장소와 연결을 설정합니다.
  3. 전송이 완료되면, Workhorse는 Rails와 요청을 완료합니다.
  4. 객체 저장소의 임시 파일을 삭제하여 업로드를 완료합니다.

이 전략은 Workhorse 지원의 다른 형태입니다. Workhorse와 Puma가 모두 접근할 수 있는 공유 저장소에 의존하지 않습니다.

기존 업로드 전략 중에서 직접 업로드는 큰(기가바이트) 업로드를 처리하는 데 가장 적합합니다.

디스크 버퍼링 업로드

직접 업로드는 객체 저장소 설정 내에서 direct_upload가 비활성화될 때 _디스크 버퍼링 업로드_로 전환됩니다. /authorize 호출에 대한 응답에는 파일 시스템 경로만 포함됩니다.

sequenceDiagram participant c as 클라이언트 participant w as Workhorse participant r as Rails participant os as 객체 저장소 activate c c ->>+w: POST /some/url/upload w ->>+r: POST /some/url/upload/authorize Note over w,r: 이 요청은 빈 본문을 가집니다. r-->>-w: 서명된 OS URL w->>+os: PUT 파일 Note over w,os: 파일이 임시 위치에 저장됩니다. Rails가 대상을 선택합니다. os-->>-w: 요청 결과 w->>+r: POST /some/url/upload Note over w,r: 파일이 위치 및 기타 메타데이터로 대체되었습니다. r->>+os: 객체를 최종 목적지로 이동 os-->>-r: 요청 결과 opt 비동기 처리 필요 r->>+redis: 작업 예약 redis-->>-r: 작업이 예약됨 end r-->>-c: 요청 결과 deactivate c w->>-w: 정리 opt 비동기 처리 필요 activate sidekiq sidekiq->>+redis: 작업 가져오기 redis-->>-sidekiq: 작업 sidekiq->>+os: 객체 가져오기 os-->>-sidekiq: 파일 sidekiq->>sidekiq: 파일 처리 deactivate sidekiq end

Workhorse 지원 업로드

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

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

업로드에 대한 추가 정보는 Workhorse 핸들러를 참조하세요.