재개 가능한 업로드

예시로 이동

이 페이지에서는 Cloud Storage의 재개 가능한 업로드에 대해 설명합니다. 재개 가능한 업로드는 대용량 파일을 업로드할 때 권장되는 방법입니다. 업로드가 진행되는 동안 네트워크 장애가 발생해도 처음부터 다시 시작할 필요가 없기 때문입니다.

소개

재개 가능한 업로드를 사용하면 통신 장애로 인해 데이터 흐름이 중단된 후 Cloud Storage로의 데이터 전송 작업을 재개할 수 있습니다. 재개 가능한 업로드는 업로드하는 객체의 일부를 포함하는 여러 요청을 전송하여 이루어집니다. 이는 단일 요청에 모든 객체 데이터를 포함하고 중간에 실패하면 처음부터 다시 시작해야 하는 단일 요청 업로드와 다른 업로드입니다.

  • 대용량 파일을 업로드하거나 느린 연결을 통해 업로드하는 경우 재개 가능한 업로드를 사용하세요. 재개 가능한 업로드를 사용하기 위한 파일 크기 축소의 예시는 업로드 크기 고려사항을 참조하세요.

  • 재개 가능한 업로드는 시작된 후 1주일 이내에 완료되어야 합니다.

  • 완료된 재개 가능한 업로드만 버킷에 표시되며 해당하는 경우 동일한 이름의 기존 객체를 대체합니다.

    • 객체 생성 시간은 업로드가 완료된 시점을 기준으로 합니다.
    • 사용자가 설정한 객체 메타데이터가 초기 요청에서 지정됩니다. 업로드가 완료되면 이 메타데이터가 객체에 적용됩니다.
  • 완료된 재개 가능한 업로드는 하나의 A 클래스 작업으로 간주됩니다.

도구 및 API가 재개 가능한 업로드를 사용하는 방법

재개 가능한 업로드는 사용자가 Cloud Storage와 어떻게 상호작용하는지에 따라 사용자를 대신하여 자동으로 관리될 수 있습니다. 이 섹션에서는 다양한 도구의 재개 가능한 업로드 동작을 설명하고 애플리케이션에 적합한 버퍼 사이즈를 구성하는 방법을 소개합니다.

콘솔

콘솔은 사용자를 대신하여 재개 가능한 업로드를 자동으로 관리합니다. 하지만 업로드가 진행되는 동안 콘솔을 새로고침하거나 벗어나면 업로드가 취소됩니다.

명령줄

gcloud

gcloud 명령줄 도구는 Cloud Storage에 데이터를 업로드할 때 gcloud alpha storage cp 명령어에서 재개 가능한 업로드를 사용합니다. 업로드가 중단되면 업로드를 시작할 때 사용한 것과 동일한 명령어를 실행하여 재개할 수 있습니다. 여러 파일이 포함된 업로드를 재개하는 경우 --no-clobber 플래그를 사용하면 업로드가 이미 완료된 파일이 다시 업로드되지 않습니다.

gsutil

gsutil 명령줄 도구는 Cloud Storage에 데이터를 업로드할 때 gsutil cp 명령어와 gsutil rsync 명령어에서 재개 가능한 업로드를 사용합니다. 업로드가 중단되면 업로드를 시작할 때 사용한 것과 동일한 명령어를 실행하여 재개할 수 있습니다. 여러 파일이 포함된 gsutil cp 업로드를 재개하는 경우 -n 플래그를 사용하면 업로드가 이미 완료된 파일이 다시 업로드되지 않습니다.

boto 구성 파일resumable_threshold 매개변수로 재개 가능한 업로드를 수행하기 위한 최소 크기를 설정할 수 있습니다. resumable_threshold의 기본값은 8MiB입니다.

클라이언트 라이브러리

C++

storage::Client의 함수는 다음과 같이 서로 다른 동작으로 수행됩니다.

  • Client::WriteObject()는 항상 재개 가능한 업로드를 수행합니다.
  • Client::InsertObject()는 항상 간단한 업로드 또는 멀티파트 업로드를 수행합니다.
  • Client::UploadFile()은 재개 가능한 업로드, 간단한 업로드 또는 멀티파트 업로드를 수행할 수 있습니다.

기본적으로 UploadFile()에서는 객체가 20MiB 이상이면 재개 가능한 업로드를 수행합니다. 그 밖의 경우 간단한 업로드 또는 멀티파트 업로드를 수행합니다. storage::Client를 만들 때 MaximumSimpleUploadsSizeOption을 설정하여 기준을 구성할 수 있습니다.

기본 버퍼 사이즈는 8MiB이며 UploadBufferSizeOption 옵션을 사용해 수정할 수 있습니다.

C++ 클라이언트 라이브러리는 청크 크기와 동일한 버퍼 사이즈를 사용합니다. 버퍼 사이즈는 256KiB(256 x 1,024바이트)의 배수여야 합니다. WriteObject()UploadFile()을 사용할 때는 업로드 속도와 메모리 사용량 간의 상충 관계를 고려해야 할 수 있습니다. 큰 객체를 업로드할 때 작은 버퍼를 사용하면 업로드 속도가 느려질 수 있습니다. C++의 업로드 속도와 버퍼 사이즈 간의 관계에 대한 자세한 내용은 GitHub의 세부 분석을 참조하세요.

C#

업로드 시 C# 클라이언트 라이브러리에서 항상 재개 가능한 업로드를 수행합니다. CreateObjectUploader를 사용하여 재개 가능한 업로드를 시작할 수 있습니다.

C# 클라이언트 라이브러리는 청크 크기와 동일한 버퍼 사이즈를 사용합니다. 기본 버퍼 사이즈는 10MB이며 UploadObjectOptions에서 ChunkSize를 설정하여 이 값을 변경할 수 있습니다. 버퍼 사이즈는 256KiB(256 x 1,024바이트)의 배수여야 합니다. 버퍼 사이즈가 클수록 업로드 속도가 빨라지지만 속도와 메모리 사용량 간에 상충 관계가 있습니다.

Go

기본적으로 재개 가능한 업로드는 파일이 16MiB보다 크면 자동으로 수행됩니다. Writer.ChunkSize를 사용하여 재개 가능한 업로드 수행을 위해 컷오프를 변경합니다. Go 클라이언트 라이브러리를 사용하면 재개 가능한 업로드가 항상 분할됩니다.

객체가 Writer.ChunkSize보다 작거나 Writer.ChunkSize가 0으로 설정되어 분할이 중지되면 멀티파트 업로드가 발생합니다. ChunkSize가 0으로 설정된 경우 Writer에서 요청을 재시도할 수 없습니다.

Go 클라이언트 라이브러리는 청크 크기와 동일한 버퍼 사이즈를 사용합니다. 버퍼 사이즈는 256KiB(256 x 1,024바이트)의 배수여야 합니다. 버퍼 사이즈가 클수록 업로드 속도가 빨라지지만 속도와 메모리 사용량 간에 상충 관계가 있습니다. 재개 가능한 업로드 여러 건을 동시에 실행할 경우에는 Writer.ChunkSize를 16MiB보다 작은 값으로 설정하여 메모리 블로트를 피해야 합니다.

Writer.Close()를 호출하고 성공 응답을 받기 전에는 객체가 Cloud Storage에서 완료되지 않습니다. 요청이 실패하면 Writer.Close에서 오류를 반환합니다.

자바

자바 클라이언트 라이브러리에는 멀티파트 및 재개 가능한 업로드에 대한 별도의 메서드가 있습니다. 다음 메서드는 항상 재개 가능한 업로드를 수행합니다.

기본 버퍼 사이즈는 15MiB입니다. WriteChannel#setChunkSize(int) 메서드를 사용하거나 bufferSize 매개변수를 Storage#createFrom 메서드에 전달하여 버퍼 사이즈를 설정할 수 있습니다. 버퍼 사이즈는 최소 256KiB입니다. 내부적으로 WriteChannel#setChunkSize(int)를 호출하면 버퍼 사이즈가 256KiB의 배수로 전환됩니다.

재개 가능한 업로드를 위한 버퍼링이 최소 플러시 기준으로 작동합니다. 버퍼 사이즈보다 작은 쓰기는 쓰기가 버퍼링된 버퍼 수를 버퍼 사이즈 이상으로 푸시할 때까지 버퍼링됩니다.

소량의 데이터를 업로드하는 경우 Storage#create(BlobInfo, byte[], Storage.BlobTargetOption...) 또는 Storage#create(BlobInfo, byte[], int, int, Storage.BlobTargetOption...)을 사용하는 것이 좋습니다.

Node.js

재개 가능한 업로드가 자동으로 발생합니다. UploadOptions에서 resumablefalse로 설정하여 재개 가능한 업로드를 사용 중지할 수 있습니다. createWriteStream 메서드를 사용하면 재개 가능한 업로드가 자동으로 관리됩니다.

기본 버퍼 사이즈는 없으며 CreateResumableUploadOptions에서 chunkSize 옵션을 설정하여 청크 업로드를 수동으로 호출해야 합니다. chunkSize가 지정되면 chunkSize 크기의 페이로드가 포함된 별도의 HTTP 요청으로 데이터가 전송됩니다. chunkSize가 지정되지 않았고 라이브러리가 재개 가능한 업로드를 수행하는 경우 모든 데이터가 단일 HTTP 요청으로 스트리밍됩니다.

Node.js 클라이언트 라이브러리는 청크 크기와 동일한 버퍼 사이즈를 사용합니다. 버퍼 사이즈는 256KiB(256 x 1,024바이트)의 배수여야 합니다. 버퍼 사이즈가 클수록 업로드 속도가 빨라지지만 속도와 메모리 사용량 간에 상충 관계가 있습니다.

PHP

기본적으로 객체 크기가 5MB를 초과하면 재개 가능한 업로드가 자동으로 수행됩니다. 그렇지 않으면 멀티파트 업로드가 수행됩니다. 이 기준점은 변경할 수 없습니다. upload 함수에서 resumable 옵션을 설정하여 재개 가능한 업로드를 강제 실행할 수 있습니다.

PHP 클라이언트 라이브러리는 청크 크기와 동일한 버퍼 사이즈를 사용합니다. 재개 가능한 업로드의 기본 버퍼 사이즈는 256KiB이며 chunkSize 속성을 설정하여 버퍼 사이즈를 변경할 수 있습니다. 버퍼 사이즈는 256KiB(256 x 1,024바이트)의 배수여야 합니다. 버퍼 사이즈가 클수록 업로드 속도가 빨라지지만 속도와 메모리 사용량 간에 상충 관계가 있습니다.

Python

객체가 8MiB보다 크면 재개 가능한 업로드가 발생하고, 객체가 8MiB보다 작으면 멀티파트 업로드가 발생합니다. 이 기준은 변경할 수 없습니다. Python 클라이언트 라이브러리는 청크 크기와 동일한 버퍼 사이즈를 사용합니다. 재개 가능한 업로드의 기본 버퍼 사이즈는 100MiB이며 blob.chunk_size 속성을 설정하여 버퍼 사이즈를 변경할 수 있습니다.

객체 크기와 관계없이 항상 재개 가능한 업로드를 수행하려면 storage.BlobWriter 클래스 또는 storage.Blob.open(mode='w') 메서드를 사용합니다. 이러한 메서드의 경우 기본 버퍼 크기는 40MiB입니다. 재개 가능한 미디어를 사용하면 재개 가능한 업로드를 관리할 수도 있습니다.

청크 크기는 256KiB(256 x 1,024바이트)의 배수여야 합니다. 청크 크기가 클수록 일반적으로 업로드 속도가 빨라지지만 속도와 메모리 사용량 간에는 상충 관계가 있습니다.

Ruby

Ruby 클라이언트 라이브러리는 모든 업로드를 분할되지 않은 재개 가능한 업로드로 취급합니다.

REST API

JSON API

Cloud Storage JSON API는 쿼리 매개변수 uploadType=resumable이 포함된 POST Object 요청을 사용하여 재개 가능한 업로드를 시작합니다. 이 요청은 그 다음에 하나 이상의 PUT Object 요청에 사용하여 객체 데이터를 업로드하는 세션 URI로 반환됩니다. 재개 가능한 업로드를 수행하기 위해 자체 로직을 빌드하는 단계별 가이드는 재개 가능한 업로드 수행을 참조하세요.

XML API

Cloud Storage XML API는 x-goog-resumable: start 헤더가 포함된 POST Object 요청을 사용하여 재개 가능한 업로드를 시작합니다. 이 요청은 그 다음에 하나 이상의 PUT Object 요청에 사용하여 객체 데이터를 업로드하는 세션 URI로 반환됩니다. 재개 가능한 업로드를 수행하기 위해 자체 로직을 빌드하는 단계별 가이드는 재개 가능한 업로드 수행을 참조하세요.

알 수 없는 크기의 재개 가능한 업로드

재개 가능한 업로드 메커니즘은 파일 크기를 미리 알 수 없는 전송을 지원합니다. 이는 업로드 도중 객체를 압축하는 경우 등에 유용할 수 있습니다. 전송이 시작될 때 압축된 파일의 정확한 파일 크기를 예측하기 어렵기 때문입니다. 이 메커니즘은 중단 후 재개할 수 있는 전송을 스트리밍하려는 경우 또는 단위 분할된 전송 인코딩이 애플리케이션에서 작동하지 않는 경우에 유용합니다.

자세한 내용은 스트리밍 이전을 참조하세요.

업로드 성능

세션 리전 선택

재개 가능한 업로드는 업로드가 시작되는 리전에 고정됩니다. 예를 들어 미국에서 재개 가능한 업로드를 시작하고 세션 URI를 아시아의 클라이언트에 제공하는 경우에도 업로드는 여전히 미국을 거치게 됩니다. 리전 간 트래픽을 줄이고 성능을 개선하려면 생성된 리전에서 재개 가능한 업로드 세션을 유지해야 합니다.

Compute Engine 인스턴스를 사용하여 재개 가능한 업로드를 시작하는 경우 인스턴스는 업로드하는 Cloud Storage 버킷과 같은 위치에 있어야 합니다. 그런 다음에 지역 IP 서비스를 사용하여 고객 요청을 라우팅할 Compute Engine 리전을 선택할 수 있습니다. 이렇게 하면 트래픽을 리전에 맞게 현지화하는 데 도움이 됩니다.

단위별 업로드

가능하면 전송을 작은 단위로 나누지 말고, 전체 콘텐츠를 하나의 단위로 업로드하세요. 단위별로 생성되는 것을 방지하면 각 단위에 대한 유지 오프셋을 쿼리할 때 발생하는 지연 시간 비용과 작업 요금이 청구되지 않으며 처리량이 향상됩니다. 하지만 다음과 같은 경우에는 단위별로 업로드하는 것을 고려해야 합니다.

  • 소스 데이터가 동적으로 생성되는 중인데 업로드가 실패하는 경우 클라이언트 측에서 버퍼링해야 하는 양을 제한하고 싶습니다.

  • 여러 브라우저의 경우와 마찬가지로 클라이언트에는 요청 크기 제한이 있습니다.

JSON 또는 XML API를 사용 중이고 클라이언트가 오류를 수신한 경우, 유지된 오프셋을 서버에 쿼리하고 해당 오프셋에서 나머지 바이트의 업로드를 재개할 수 있습니다. 콘솔, gsutil, gcloud, 클라이언트 라이브러리가 이를 자동으로 처리합니다. 특정 클라이언트 라이브러리의 단위 분할에 대한 자세한 내용은 재개 가능한 업로드 동작을 참조하세요.

고려사항

이 섹션은 재개 가능한 업로드 요청을 JSON 또는 XML API로 직접 보내는 자체 클라이언트를 빌드하는 경우에 유용합니다.

세션 URI

재개 가능한 업로드를 시작하면 Cloud Storage는 세션 URI를 반환합니다. 이 URI는 후속 요청에서 실제 데이터를 업로드하는 데 사용됩니다. JSON API의 세션 URI 예시는 다음과 같습니다.

https://storage.googleapis.com/upload/storage/v1/b/my-bucket/o?uploadType=resumable&name=my-file.jpg&upload_id=ABg5-UxlRQU75tqTINorGYDgM69mX06CzKO1NRFIMOiuTsu_mVsl3E-3uSVz65l65GYuyBuTPWWICWkinL1FWcbvvOA

XML API의 세션 URI 예시는 다음과 같습니다.

 https://storage.googleapis.com/my-bucket/my-file.jpg?upload_id=ABg5-UxlRQU75tqTINorGYDgM69mX06CzKO1NRFIMOiuTsu_mVsl3E-3uSVz65l65GYuyBuTPWWICWkinL1FWcbvvOA

이 세션 URI는 인증 토큰 역할을 하므로 이 토큰을 사용하는 요청은 서명이 필요 없으며 누구나 추가 인증 없이 대상 버킷에 데이터를 업로드하는 데 사용할 수 있습니다. 그러므로 세션 URI를 공유할 때는 신중을 기하고 HTTPS를 통해서만 공유하세요.

세션 URI는 일주일 후에 만료되지만 만료되기 전에 취소할 수 있습니다. 더 이상 유효하지 않은 세션 URI를 사용하여 요청하면 다음 오류 중 하나가 표시됩니다.

  • 업로드가 시작된 후 1주일이 지나지 않은 경우 410 Gone 상태 코드
  • 업로드가 시작된 후 1주일을 초과한 경우 404 Not Found 상태 코드

두 경우 모두 재개 가능한 새 업로드를 시작하고, 새 세션 URI를 가져오고, 새 세션 URI를 사용하여 업로드를 처음부터 시작해야 합니다.

무결성 검사

소스 파일과 일치하는지 확인하기 위해 최종 업로드된 객체의 무결성 검사를 요청하는 것이 좋습니다. 소스 파일의 MD5 다이제스트를 계산하여 Content-MD5 요청 헤더에 추가하면 됩니다.

장기간에 걸쳐 대용량 파일을 업로드하는 경우 업로드 작업 중에 소스 파일이 수정될 가능성이 높기 때문에 업로드된 파일의 무결성 검사가 특히 중요합니다.

다시 전송된 데이터

Cloud Storage가 재개 가능한 업로드에서 바이트를 유지하는 경우 이 바이트를 덮어쓸 수 없으며, Cloud Storage는 이를 시도하지 않습니다. 따라서 이전에 전송한 오프셋까지 되감을 때 다른 데이터를 전송해서는 안 됩니다.

예를 들어 100,000바이트 객체를 업로드하는데 연결이 중단되었다고 가정해 보겠습니다. 상태 확인을 수행하면 50,000바이트가 성공적으로 업로드 및 유지된 것으로 확인됩니다. 40,000바이트부터 업로드를 다시 시작하려고 하면 Cloud Storage는 40,000에서 50,000까지 전송되는 바이트를 무시합니다. Cloud Storage는 50,001바이트부터 전송되는 바이트를 유지하기 시작합니다.

다음 단계