업로드 개발 가이드라인
업로드는 많은 GitLab 기능의 필수적인 부분입니다. GitLab이 업로드를 처리하는 방법을 이해하기 위해, 이 페이지는 파일을 저장할 대상에 대한 주요 메커니즘에 대한 개요를 제공합니다.
GitLab 업로드는 기능별로 구성됩니다. 업로드를 포함하는 모든 기능은 동일한 구성 옵션을 제공하지만, 각각 독립적으로 구성할 수 있습니다. 예를 들어, Git LFS 업로드는 CI/CD 빌드 아티팩트 업로드와 독립적으로 구성될 수 있지만, 두 경우 모두 동일한 설정 키를 제공합니다. 이러한 설정은 업로드가 처리되는 방식을 규제하며, 성능과 확장성에 중대한 영향을 미칠 수 있습니다.
이 페이지에서는 해당 파일을 처리하는 데 중요한 업로드 설정을 요약하고, 그 다음으로 각 메커니즘을 더 자세히 설명합니다.
업로드 설정이 업로드 흐름을 구동하는 방법
개별 업로드 전략을 보다 자세히 살펴보기 전에, 각 업로드 설정이 이러한 전략과 매핑되는 고수준 요약을 살펴봅시다.
업로드 설정 자체는 업로드 관리 문서에 기록되어 있습니다. 여기서 우리는 이러한 설정이 GitLab 업로드 논리의 내부를 구동하는 방식에 집중합니다. 최상위 수준에서 우리는 업로드된 파일의 두 대상을 구분합니다:
이 표에서 x.y.z
는 gitlab.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 애플리케이션 서버는 동일한 데이터에 액세스할 수 있을 때 오브젝트 스토리지에 데이터가 저장됨.
GitLab SaaS를 포함한 CNG 설치는 항상 오브젝트 스토리지를 사용합니다 (GitLab SaaS의 경우 GCS 사용).
원격 오브젝트 스토리지로 업로드하는 것의 어려움 중 하나는 GitLab에서 오브젝트 스토어 제공 업체로 나가는 HTTP 요청을 포함한다는 것입니다. 위에서 언급한 바와 같이, 이 HTTP 요청이 전송되는 방식에는 세 가지 다른 전략이 있습니다.
Rails 컨트롤러 업로드
직접 업로드를 사용할 수 없을 때, Rails는 컨트롤러 create
액션의 일부로 파일을 오브젝트 스토리지로 업로드합니다. 업로드 된 파일의 종류에 따라 책임을 지는 컨트롤러가 다릅니다.
Rails 컨트롤러 업로드는 로컬 스토리지로의 업로드와 매우 유사합니다. 주요 차이점은 Rails가 오브젝트 스토리지로 HTTP 요청을 보내야 한다는 것입니다. 이는 CarrierWave Fog 업로더를 통해 발생합니다.
로컬 스토리지와 마찬가지로 이 전략은 Workhorse 지원을 받아들이며, 이는 비용이 많이 드는 I/O 작업 중 일부를 Ruby와 Rails에서 빼냅니다. 직접 업로드는 더 나은 일을 합니다. 왜냐하면 이 방법은 또한 오브젝트 스토리지로의 HTTP PUT 요청을 Puma 밖으로 내보내기 때문입니다.
이 전략은 Puma의 60초 요청 시간 초과에 영향을 받는 경우에는 작은 파일 업로드에만 적합합니다.
직접 업로드
직접 업로드는 GitLab SaaS와 같은 CNG 설치에서 큰 파일을 오브젝트 스토리지로 이동하는 권장 방법입니다.
직접 업로드를 사용하면 Workhorse가 다음을 수행합니다:
- 요청을 Rails로 인증합니다.
- 오브젝트 스토어 자체와 연결을 설정하여 파일을 임시 위치로 전송합니다.
- 전송이 완료되면, Workhorse가 요청을 Rails로 완료합니다. Rails는 파일을 최종 위치로 이동시키기 위해 오브젝트 스토어 복사 작업을 수행합니다.
- 오브젝트 스토리지의 임시 파일을 삭제하여 업로드를 완료합니다.
이 전략은 Workhorse 지원의 다른 형태입니다. Workhorse와 Puma 모두가 액세스할 수 있는 공유 스토리지에 의존하지 않으며, 큰(기가바이트) 업로드를 처리하는 데 가장 적합합니다. 그러나, Puma는 여전히 긴급한 요청을 처리하므로, 업로드 크기에 비례하는 시간이 소요되는 오브젝트 스토리지 복사 작업에 칠 수 있는 시간 초과 가능성이 남아 있습니다.
Workhorse 지원 업로드
대부분의 업로드는 어떤 방식으로든, Workhorse로부터 도움을 받습니다.
- 종종, Workhorse는 업로드를 일시적인 파일에 버퍼링합니다. Workhorse는 Puma에게 임시 파일의 이름과 위치를 알리기 위해 요청에 메타데이터를 추가합니다. 이는 Workhorse와 Puma 사이에 공유된 임시 스토리지를 요구합니다. 모든 GitLab 설치 (CNG 포함)는 이 공유 임시 스토리지를 가지고 있습니다.
- Workhorse는 때로 파일을 사전 처리합니다. 예를 들어, CI 아티팩트 업로드의 경우, Workhorse는 ZIP 파일의 내용에 대한 별도의 색인을 생성합니다. 이를 통해 Puma 요청 시간 초과를 우회합니다. Sidekiq 백그라운드 처리와 비교하면, 사용자가 파일을 수용하지만 아직 처리하지 않은 중간 상태를 볼 수 없는 이점이 있습니다.
- 직접 업로드의 경우, Workhorse가 파일을 사전 처리하고 오브젝트 스토리지로 업로드할 수 있습니다. 큰 파일을 오브젝트 스토리지에 업로드하는 데 시간이 걸리는데, 이를 통해 Puma 요청 시간 초과를 피할 수 있습니다.