AWS SDK for PHP 버전 3에서 Amazon S3 멀티파트 업로드 사용 - AWS SDK for PHP

기계 번역으로 제공되는 번역입니다. 제공된 번역과 원본 영어의 내용이 상충하는 경우에는 영어 버전이 우선합니다.

AWS SDK for PHP 버전 3에서 Amazon S3 멀티파트 업로드 사용

단일 PutObject 작업으로 최대 5GB 크기의 객체를 업로드할 수 있습니다. 하지만 멀티파트 업로드 메서드(예: CreateMultipartUpload, UploadPart, CompleteMultipartUpload, AbortMultipartUpload)를 사용하면 5MB ~ 5TB 크기의 객체를 업로드할 수 있습니다.

다음 예에서는 작업 방법을 보여줍니다.

  • 를 사용하여 Amazon S3에 객체를 ObjectUploader업로드합니다.

  • 를 사용하여 MultipartUploaderAmazon S3 객체에 대한 멀티파트 업로드를 생성합니다.

  • 를 사용하여 한 Amazon S3 위치에서 다른 위치로 객체를 ObjectCopier복사합니다.

의 모든 예제 코드는 여기에서 확인할 수 GitHub 있습니다. AWS SDK for PHP

보안 인증 정보

예제 코드를 실행하기 전에 보안 인증에 설명된 대로 AWS 보안 인증을 구성합니다. 그 다음 기본 사용법에 설명된 AWS SDK for PHP를 가져옵니다.

객체 업로더

PutObjectMultipartUploader 중에서 어떤 것이 작업에 가장 적합한지 잘 모를 경우에는 ObjectUploader를 사용하세요. ObjectUploaderPutObject 또는 MultipartUploader 중에서 페이로드 크기를 기준으로 가장 적합한 것을 사용해 대용량 파일 하나를 Amazon S3에 업로드합니다.

require 'vendor/autoload.php'; use Aws\Exception\MultipartUploadException; use Aws\S3\MultipartUploader; use Aws\S3\ObjectUploader; use Aws\S3\S3Client;

샘플 코드

// Create an S3Client. $s3Client = new S3Client([ 'profile' => 'default', 'region' => 'us-east-2', 'version' => '2006-03-01' ]); $bucket = 'your-bucket'; $key = 'my-file.zip'; // Use a stream instead of a file path. $source = fopen('/path/to/large/file.zip', 'rb'); $uploader = new ObjectUploader( $s3Client, $bucket, $key, $source ); do { try { $result = $uploader->upload(); if ($result["@metadata"]["statusCode"] == '200') { print('<p>File successfully uploaded to ' . $result["ObjectURL"] . '.</p>'); } print($result); // If the SDK chooses a multipart upload, try again if there is an exception. // Unlike PutObject calls, multipart upload calls are not automatically retried. } catch (MultipartUploadException $e) { rewind($source); $uploader = new MultipartUploader($s3Client, $source, [ 'state' => $e->getState(), ]); } } while (!isset($result)); fclose($source);

구성

ObjectUploader 객체 생성자는 다음 인수를 받습니다.

$client

전송을 수행하는 데 사용할 Aws\ClientInterface 객체입니다. 이 객체는 Aws\S3\S3Client의 인스턴스여야 합니다.

$bucket

(string, 필수) 객체가 업로드되는 버킷의 이름입니다.

$key

(string, 필수) 업로드되는 객체에 사용할 키입니다.

$body

(mixed, 필수) 업로드할 객체 데이터. StreamInterface일 수 있습니다, PHP 스트림 리소스 또는 업로드할 데이터 문자열일 수 있습니다.

$acl

(string) 업로드되는 객체에서 설정할 ACL(액세스 제어 목록)입니다. 객체는 기본적으로 프라이빗입니다.

$options

멀티파트 업로드에 대한 구성 옵션의 결합형 배열입니다. 유효한 구성 옵션은 다음과 같습니다.

add_content_md5

(bool) true로 설정하면 업로드에 필요한 MD5 체크섬이 자동으로 계산됩니다.

mup_threshold

(int, 기본값: int(16777216)) 파일 크기의 바이트 수입니다. 파일 크기가 이 제한을 초과하는 경우 멀티파트 업로드가 사용됩니다.

before_complete

(callable) CompleteMultipartUpload 작업 이전에 호출할 콜백입니다. 콜백에는 function (Aws\Command $command) {...}와 같은 함수 서명이 있어야 합니다.

before_initiate

(callable) CreateMultipartUpload 작업 이전에 호출할 콜백입니다. 콜백에는 function (Aws\Command $command) {...}와 같은 함수 서명이 있어야 합니다.

before_upload

(callable) 모든 PutObject 또는 UploadPart 작업 이전에 호출할 콜백입니다. 콜백에는 function (Aws\Command $command) {...}와 같은 함수 서명이 있어야 합니다.

concurrency

(int, 기본값: int(3)) 멀티파트 업로드 중에 허용되는 최대 동시 실행 UploadPart 작업 수입니다.

part_size

(int, 기본값: int(5242880)) 멀티파트 업로드를 수행할 때 사용할 부분 크기(바이트)입니다. 값은 5MB에서 5GB 사이(포함)이어야 합니다.

state

(Aws\Multipart\UploadState) 멀티파트 업로드의 상태를 나타내며 이전 업로드를 다시 시작하는 데 사용되는 객체입니다. 이 옵션을 제공하면 $bucket, $key 인수 및 part_size 옵션이 무시됩니다.

MultipartUploader

멀티파트 업로드는 대용량 객체의 업로드 경험을 개선하기 위해 디자인되었습니다. 이 메서드를 사용하면 객체를 독립적인 부분으로 어떤 순서로든 병렬로 업로드할 수 있습니다.

Amazon S3 고객은 100MB를 초과하는 객체에 멀티파트 업로드를 사용하는 것이 좋습니다.

MultipartUploader 객체

SDK에는 멀티파트 업로드 프로세스를 간소화하는 특수한 MultipartUploader 객체가 있습니다.

가져오기

require 'vendor/autoload.php'; use Aws\Exception\MultipartUploadException; use Aws\S3\MultipartUploader; use Aws\S3\S3Client;

샘플 코드

$s3Client = new S3Client([ 'profile' => 'default', 'region' => 'us-west-2', 'version' => '2006-03-01' ]); // Use multipart upload $source = '/path/to/large/file.zip'; $uploader = new MultipartUploader($s3Client, $source, [ 'bucket' => 'your-bucket', 'key' => 'my-file.zip', ]); try { $result = $uploader->upload(); echo "Upload complete: {$result['ObjectURL']}\n"; } catch (MultipartUploadException $e) { echo $e->getMessage() . "\n"; }

업로더는 제공된 소스와 구성을 기반으로 부분 데이터 생성기를 생성하고 모든 부분을 업로드하려고 시도합니다. 일부 부분 업로드가 실패하면 업로더는 전체 소스 데이터를 읽을 때까지 이후 부분을 계속해서 업로드합니다. 그런 다음 업로더가 실패한 부분을 다시 업로드하거나, 혹은 업로드에 실패한 부분에 대한 정보가 포함된 예외를 발생시킵니다.

멀티파트 업로드 사용자 지정

생성기에 전달된 콜백을 통해 멀티파트 업로더에서 실행되는 CreateMultipartUpload, UploadPartCompleteMultipartUpload 작업에 대해 사용자 지정 옵션을 설정할 수 있습니다.

가져오기

require 'vendor/autoload.php'; use Aws\S3\MultipartUploader; use Aws\S3\S3Client;

샘플 코드

// Create an S3Client $s3Client = new S3Client([ 'profile' => 'default', 'region' => 'us-west-2', 'version' => '2006-03-01' ]); // Customizing a multipart upload $source = '/path/to/large/file.zip'; $uploader = new MultipartUploader($s3Client, $source, [ 'bucket' => 'your-bucket', 'key' => 'my-file.zip', 'before_initiate' => function (Command $command) { // $command is a CreateMultipartUpload operation $command['CacheControl'] = 'max-age=3600'; }, 'before_upload' => function (Command $command) { // $command is an UploadPart operation $command['RequestPayer'] = 'requester'; }, 'before_complete' => function (Command $command) { // $command is a CompleteMultipartUpload operation $command['RequestPayer'] = 'requester'; }, ]);

부분 업로드 간 수동 가비지 수집

대용량 업로드로 인해 메모리 제한에 도달한 경우에는 메모리 제한에 도달했을 때 PHP 가비지 수집기에서 수집된 순환 참조가 아닌, SDK에서 생성된 순환 참조가 원인일 수 있습니다. 이때는 작업 사이에 수집 알고리즘을 직접 호출하면 제한에 도달하기 전에 순환 참조를 수집할 수 있습니다. 다음 예제는 각 부분 업로드 전에 콜백을 사용해 수집 알고리즘을 호출하는 것입니다. 단, 가비지 수집기를 호출할 경우 성능 비용이 발생하므로 사용 사례와 환경에 따라 사용하는 것이 좋습니다.

$uploader = new MultipartUploader($client, $source, [ 'bucket' => 'your-bucket', 'key' => 'your-key', 'before_upload' => function(\Aws\Command $command) { gc_collect_cycles(); } ]);

오류 복구

멀티파트 업로드 프로세스 중에 오류가 발생하면 MultipartUploadException이 발생합니다. 이 예외는 멀티파트 업로드의 진행률 정보가 포함된 UploadState 객체에 대한 액세스를 제공합니다. UploadState를 사용하여 완료하지 못한 업로드를 다시 시작할 수 있습니다.

가져오기

require 'vendor/autoload.php'; use Aws\Exception\MultipartUploadException; use Aws\S3\MultipartUploader; use Aws\S3\S3Client;

샘플 코드

// Create an S3Client $s3Client = new S3Client([ 'profile' => 'default', 'region' => 'us-west-2', 'version' => '2006-03-01' ]); $source = '/path/to/large/file.zip'; $uploader = new MultipartUploader($s3Client, $source, [ 'bucket' => 'your-bucket', 'key' => 'my-file.zip', ]); //Recover from errors do { try { $result = $uploader->upload(); } catch (MultipartUploadException $e) { $uploader = new MultipartUploader($s3Client, $source, [ 'state' => $e->getState(), ]); } } while (!isset($result)); //Abort a multipart upload if failed try { $result = $uploader->upload(); } catch (MultipartUploadException $e) { // State contains the "Bucket", "Key", and "UploadId" $params = $e->getState()->getId(); $result = $s3Client->abortMultipartUpload($params); }

UploadState에서 업로드를 다시 시작하면 아직 업로드되지 않은 부분을 업로드하려고 시도합니다. 상태 객체는 업로드가 연속적이 아닌 경우 누락된 부분을 계속 추적합니다. 업로더는 제공된 소스 파일을 아직도 업로드해야 하는 부분에 속한 바이트 범위까지 세부적으로 읽거나 탐색합니다.

UploadState 객체는 직렬화 가능하므로, 다른 프로세스에서 업로드를 다시 시작할 수도 있습니다. 또한 예외를 처리하지 않을 때에도 $uploader->getState()를 호출하여 UploadState 객체를 가져올 수 있습니다.

중요

MultipartUploader에 소스로 전달된 스트림은 업로드 전에 자동으로 되감지 않습니다. 이전의 예제와 비슷한 루프에서 파일 경로 대신 스트림을 사용하는 경우 catch 블록 내부의 $source 변수를 재설정합니다.

가져오기

require 'vendor/autoload.php'; use Aws\Exception\MultipartUploadException; use Aws\S3\MultipartUploader; use Aws\S3\S3Client;

샘플 코드

// Create an S3Client $s3Client = new S3Client([ 'profile' => 'default', 'region' => 'us-west-2', 'version' => '2006-03-01' ]); //Using stream instead of file path $source = fopen('/path/to/large/file.zip', 'rb'); $uploader = new MultipartUploader($s3Client, $source, [ 'bucket' => 'your-bucket', 'key' => 'my-file.zip', ]); do { try { $result = $uploader->upload(); } catch (MultipartUploadException $e) { rewind($source); $uploader = new MultipartUploader($s3Client, $source, [ 'state' => $e->getState(), ]); } } while (!isset($result)); fclose($source);

멀티파트 업로드 중단

멀티파트 업로드는 UploadState 객체에 포함된 UploadId을 불러와 abortMultipartUpload에 전달하여 중단할 수 있습니다.

try { $result = $uploader->upload(); } catch (MultipartUploadException $e) { // State contains the "Bucket", "Key", and "UploadId" $params = $e->getState()->getId(); $result = $s3Client->abortMultipartUpload($params); }

비동기 멀티파트 업로드

upload()에서 MultipartUploader를 호출하는 것은 차단 요청입니다. 비동기 콘텍스트에서 작업하는 경우 멀티파트 업로드에 대한 promise를 가져올 수 있습니다.

require 'vendor/autoload.php'; use Aws\S3\MultipartUploader; use Aws\S3\S3Client;

샘플 코드

// Create an S3Client $s3Client = new S3Client([ 'profile' => 'default', 'region' => 'us-west-2', 'version' => '2006-03-01' ]); $source = '/path/to/large/file.zip'; $uploader = new MultipartUploader($s3Client, $source, [ 'bucket' => 'your-bucket', 'key' => 'my-file.zip', ]); $promise = $uploader->promise();

구성

MultipartUploader 객체 생성자는 다음 인수를 받습니다.

$client

전송을 수행하는 데 사용할 Aws\ClientInterface 객체입니다. 이 객체는 Aws\S3\S3Client의 인스턴스여야 합니다.

$source

업로드되는 소스 데이터입니다. 이 데이터는 경로 또는 URL(예: /path/to/file.jpg), 리소스 핸들(예: fopen('/path/to/file.jpg', 'r)) 또는 PSR-7 스트림의 인스턴스일 수 있습니다.

$config

멀티파트 업로드에 대한 구성 옵션의 결합형 배열입니다.

유효한 구성 옵션은 다음과 같습니다.

acl

(string) 업로드되는 객체에서 설정할 ACL(액세스 제어 목록)입니다. 객체는 기본적으로 프라이빗입니다.

before_complete

(callable) CompleteMultipartUpload 작업 이전에 호출할 콜백입니다. 콜백에는 function (Aws\Command $command) {...}와 같은 함수 서명이 있어야 합니다.

before_initiate

(callable) CreateMultipartUpload 작업 이전에 호출할 콜백입니다. 콜백에는 function (Aws\Command $command) {...}와 같은 함수 서명이 있어야 합니다.

before_upload

(callable) 모든 UploadPart 작업 이전에 호출할 콜백입니다. 콜백에는 function (Aws\Command $command) {...}와 같은 함수 서명이 있어야 합니다.

bucket

(string, 필수) 객체가 업로드되는 버킷의 이름입니다.

concurrency

(int, 기본값: int(5)) 멀티파트 업로드 중에 허용되는 최대 동시 실행 UploadPart 작업 수입니다.

key

(string, 필수) 업로드되는 객체에 사용할 키입니다.

part_size

(int, 기본값: int(5242880)) 멀티파트 업로드를 수행할 때 사용할 부분 크기(바이트)입니다. 이 값은 5MB에서 5GB 사이(포함)이어야 합니다.

state

(Aws\Multipart\UploadState) 멀티파트 업로드의 상태를 나타내며 이전 업로드를 다시 시작하는 데 사용되는 객체입니다. 이 옵션을 제공하면 bucket, keypart_size 옵션이 무시됩니다.

add_content_md5

(boolean) true로 설정하면 업로드에 필요한 MD5 체크섬이 자동으로 계산됩니다.

멀티파트 복사

AWS SDK for PHP는 MultipartUploader와 비슷한 방식으로 사용되는 MultipartCopy 객체를 포함하지만, Amazon S3 내에서 5GB ~ 5TB 크기의 객체를 복사하기 위해 설계되었습니다.

require 'vendor/autoload.php'; use Aws\Exception\MultipartUploadException; use Aws\S3\MultipartCopy; use Aws\S3\S3Client;

샘플 코드

// Create an S3Client $s3Client = new S3Client([ 'profile' => 'default', 'region' => 'us-west-2', 'version' => '2006-03-01' ]); //Copy objects within S3 $copier = new MultipartCopy($s3Client, '/bucket/key?versionId=foo', [ 'bucket' => 'your-bucket', 'key' => 'my-file.zip', ]); try { $result = $copier->copy(); echo "Copy complete: {$result['ObjectURL']}\n"; } catch (MultipartUploadException $e) { echo $e->getMessage() . "\n"; }