디렉터리 버킷에 멀티파트 업로드 사용 - Amazon Simple Storage Service

디렉터리 버킷에 멀티파트 업로드 사용

멀티파트 업로드 프로세스를 사용하면 단일 객체를 여러 부분의 집합으로 업로드할 수 있습니다. 각 부분은 객체 데이터의 연속적인 부분입니다. 이러한 객체 부분은 독립적으로 그리고 임의의 순서로 업로드할 수 있습니다. 부분의 전송이 실패할 경우 다른 부분에 영향을 주지 않고도 해당 부분을 재전송할 수 있습니다. 객체의 모든 부분이 업로드되면 Amazon S3가 이들 부분을 수집하여 객체를 생성합니다. 일반적으로 객체 크기가 100MB에 근접할 경우, 단일 작업에서 객체를 업로드하는 대신 멀티파트 업로드 사용을 고려해 봐야 합니다.

멀티파트 업로드 사용은 다음 이점을 제공합니다.

  • 개선된 처리량 개선 - 부분을 병렬적으로 업로드하여 처리량을 개선할 수 있습니다.

  • 네트워크 문제로부터 빠른 복구 - 더 작아진 부분 크기는 네트워크 오류로 인해 실패한 업로드 재시작의 영향을 최소화합니다.

  • 객체 업로드 일시 중지 및 재개 – 객체 부분을 장시간에 걸쳐 업로드할 수 있습니다. 멀티파트 업로드가 시작되면 만료 날짜가 없습니다. 멀티파트 업로드를 명시적으로 완료하거나 중단해야 합니다.

  • 최종 객체 크기를 알기 전에 업로드를 시작 – 객체를 생성하는 동안 업로드할 수 있습니다.

다음 방법으로 멀티파트 업로드를 사용하는 것이 좋습니다.

  • 안정적인 높은 대역폭 네트워크를 통해 큰 객체를 업로드하는 경우, 멀티파트 업로드를 사용하여 멀티 스레드 성능을 위해 여러 객체 부분을 동시에 업로드함으로써 대역폭 사용을 극대화합니다.

  • 불규칙한 네트워크를 통해 업로드하는 경우, 멀티파트 업로드를 사용하여 업로드가 다시 시작되는 것을 방지하여 네트워크 오류에 대한 복원력을 높입니다. 멀티파트 업로드를 사용하는 경우, 업로드 중에 중단된 부분만 다시 업로드해야 합니다. 객체 업로드를 처음부터 다시 시작하지 않아도 됩니다.

멀티파트 업로드를 사용하여 디렉터리 버킷의 Amazon S3 Express One Zone 스토리지 클래스에 객체를 업로드하는 경우, 멀티파트 업로드 프로세스는 멀티파트 업로드를 사용하여 범용 버킷에 객체를 업로드하는 프로세스와 유사합니다. 하지만 몇 가지 큰 차이가 있습니다.

멀티파트 업로드를 사용하여 S3 Express One Zone에 객체를 업로드하는 방법에 대한 자세한 정보는 다음 주제를 참조하세요.

멀티파트 업로드 프로세스

멀티파트 업로드는 다음과 같은 3단계 프로세스입니다.

  • 업로드를 시작합니다.

  • 객체 부분을 업로드합니다.

  • 부분을 모두 업로드한 후 멀티파트 업로드를 완료합니다.

Amazon S3에 멀티파트 업로드 완료 요청이 전송되면 버킷의 다른 객체와 같이 이 객체에 액세스할 수 있도록 업로드된 각 부분을 모아 완전한 객체를 구성합니다.

멀티파트 업로드 시작

멀티파트 업로드 시작 요청을 전송하면 Amazon S3는 멀티파트 업로드에 대한 고유 식별자인 업로드 ID와 함께 응답을 반환합니다. 파트 업로드, 부분 목록 확인, 업로드 완료 또는 업로드 중단 요청 시 항상 이 업로드 ID를 포함해야 합니다.

파트 업로드

부분을 업로드할 때 업로드 ID와 함께 부분 번호를 지정해야 합니다. S3 Express One Zone에서 멀티파트 업로드를 사용하는 경우 멀티파트의 부분 번호는 연속된 번호여야 합니다. 연속되지 않는 부분 번호로 멀티파트 업로드 요청을 완료하려고 하면 HTTP 400 Bad Request(유효하지 않은 부분 순서) 오류가 생성됩니다.

부분 번호를 사용하여 업로드하는 객체에서 각 부분과 그 위치를 고유하게 식별합니다. 이전에 업로드한 부분과 동일한 부분 번호로 새 부분을 업로드할 경우 이전에 업로드한 부분을 덮어쓰게 됩니다.

부분을 업로드할 때마다 Amazon S3는 그 응답으로 엔터티 태그(ETag) 헤더를 반환합니다. 각 부분 업로드에 대해 부분 번호와 ETag 값을 기록해야 합니다. 모든 객체 파트 업로드의 ETag 값은 동일하게 유지되지만 각 파트에는 다른 파트 번호가 할당됩니다. 이후 멀티파트 업로드를 완료하기 위한 요청에 이러한 값을 포함해야 하기 때문입니다.

Amazon S3는 S3 버킷에 업로드되는 모든 새 객체를 자동으로 암호화합니다. 멀티파트 업로드를 수행할 때 요청에서 암호화 정보를 지정하지 않은 경우 업로드된 파트의 암호화 설정이 대상 버킷의 기본 암호화 구성으로 설정됩니다. Amazon S3 버킷의 기본 암호화 구성은 항상 활성화되어 있으며, 최소한 Amazon S3 관리형 키를 통한 서버 측 암호화(SSE-S3)로 설정되어 있습니다. 디렉터리 버킷의 경우 SSE-S3만 지원됩니다. 자세한 내용은 Amazon S3 관리형 키를 사용한 서버 측 암호화(SSE-S3) 단원을 참조하십시오.

멀티파트 업로드 완료

멀티파트 업로드를 완료하면 Amazon S3는 부분 번호를 바탕으로 오름차순으로 각 부분을 결합하여 객체를 완성합니다. 성공적으로 완료 요청이 수행되면 부분은 더 이상 존재하지 않습니다.

멀티파트 업로드 완료 요청에는 업로드 ID와 각 부분 번호 및 해당 ETag 값의 목록이 포함되어야 합니다. Amazon S3 응답에는 결합된 객체 데이터를 고유하게 식별하는 ETag가 포함됩니다. 이 ETag는 객체 데이터의 MD5 해시가 아닙니다.

멀티파트 업로드 나열

특정 멀티파트 업로드 또는 진행 중인 모든 멀티파트 업로드에 대해 부분 목록을 확인할 수 있습니다. 부분 목록 조회 작업은 특정 멀티파트 업로드에 대해 업로드한 부분의 정보를 반환합니다. 각 부분 목록 조회 요청에 대해 Amazon S3는 특정 멀티파트 업로드에서 최대 1,000개의 부분에 대해 부분 정보를 반환합니다. 멀티파트 업로드에서 파트가 1,000개 이상일 경우 모든 파트를 검색하려면 페이지 매김을 사용해야 합니다.

반환된 부분 목록에는 업로드가 완료되지 않은 부분이 포함되지 않습니다. 멀티파트 업로드 나열 작업을 사용하여 진행 중인 멀티파트 업로드의 목록을 확인할 수 있습니다.

진행 중인 멀티파트 업로드는 시작했지만 아직 완료 또는 중단하지 않은 업로드입니다. 각 요청은 최대 1,000개의 멀티파트 업로드를 반환합니다. 진행 중인 멀티파트 업로드가 1,000개 이상일 경우 남은 멀티파트 업로드를 모두 검색하려면 추가 요청을 전송해야 합니다. 반환된 목록은 확인을 위해서만 사용합니다. 멀티파트 업로드 완료 요청을 전송할 때 이 나열 결과를 사용하면 안 됩니다. 그 대신, 부분을 업로드할 때 지정한 부분 번호 및 Amazon S3가 반환한 해당 ETag 값의 목록을 보관해야 합니다.

멀티파트 업로드 목록에 대한 자세한 내용은 Amazon Simple Storage Service API 참조의 ListParts를 참조하세요.

멀티파트 업로드 작업을 사용한 체크섬

객체를 업로드할 때 객체 무결성을 검사하기 위해 체크섬 알고리즘을 지정할 수 있습니다. 디렉터리 버킷에는 MD5가 지원되지 않습니다. 다음 SHA(보안 해시 알고리즘) 또는 CRC(순환 중복 검사) 데이터 무결성 확인 알고리즘 중 하나를 지정할 수 있습니다.

  • 2013년 8월 9일

  • CRC32C

  • SHA-1

  • SHA-256

Amazon S3 REST API 또는 AWS를 사용하여 GetObject 또는 HeadObject를 통해 개별 부분의 체크섬 값을 검색할 수 있습니다. 아직 진행 중인 멀티파트 업로드의 개별 부분에 대한 체크섬 값을 검색하려면 ListParts를 사용하면 됩니다.

중요

이전의 체크섬 알고리즘을 사용하는 경우 멀티파트 번호에 연속된 파트 번호를 사용해야 합니다. 연속되지 않는 부분 번호로 멀티파트 업로드 요청을 완료하려고 하면 Amazon S3에서 HTTP 400 Bad Request(유효하지 않은 부분 순서) 오류가 생성됩니다.

멀티파트 객체를 통한 체크섬 작업에 대한 자세한 내용은 객체 무결성 확인 단원을 참조하십시오.

동시 멀티파트 업로드 작업

분산 개발 환경에서는 애플리케이션에서 한 객체에 대해 동시에 여러 업데이트를 시작할 수 있습니다. 예를 들어 애플리케이션은 동일한 객체 키를 사용하여 여러 멀티파트 업로드를 시작할 수 있습니다. 이러한 각 업로드에 대해 애플리케이션은 부분을 업로드한 후 Amazon S3가 객체를 생성하도록 업로드 완료 요청을 전송할 수 있습니다. S3 Express One Zone의 경우 객체 생성 시간은 멀티파트 업로드 완료 날짜입니다.

중요

디렉터리 버킷에 저장된 객체에는 버전 관리가 지원되지 않습니다.

멀티파트 업로드 및 요금

멀티파트 업로드가 시작되면 Amazon S3는 업로드가 완료되거나 중단될 때까지 모든 파트를 계속 유지합니다. 수명 주기가 끝날 때까지 이 멀티파트 업로드와 관련 부분의 모든 스토리지, 대역폭 및 요청에 대해 비용이 청구됩니다. 멀티파트 업로드를 중단하면 Amazon S3가 업로드 결과 및 업로드된 모든 파트를 삭제하므로 더 이상 비용이 청구되지 않습니다. 지정한 스토리지 클래스에 관계없이 불완전한 멀티파트 업로드를 삭제하는 경우 조기 삭제 요금이 부과되지 않습니다. 요금에 대한 자세한 내용은 Amazon S3 요금을 참조하십시오.

중요

전체 멀티파트 업로드 요청이 성공적으로 전송되지 않으면 객체 파트가 어셈블되지 않고 객체가 생성되지 않습니다. 업로드된 부분에 연결된 모든 스토리지에 대해 요금이 청구됩니다. 멀티파트 업로드를 완료하여 객체를 생성하거나 멀티파트 업로드를 중지하여 업로드된 파트를 제거하는 것이 중요합니다.

디렉터리 버킷을 삭제하기 전에 진행 중인 모든 멀티파트 업로드를 완료하거나 중단해야 합니다. 디렉터리 버킷은 S3 수명 주기 구성을 지원하지 않습니다. 필요한 경우 활성 멀티파트 업로드를 나열한 다음 업로드를 중단한 후 버킷을 삭제할 수 있습니다.

멀티파트 업로드 API 작업 및 권한

디렉터리 버킷의 객체 관리 API 작업에 대한 액세스를 허용하려면 버킷 정책 또는 AWS Identity and Access Management(IAM) ID 기반 정책에서 디렉터리 버킷에 s3express:CreateSession 권한을 부여합니다.

멀티파트 업로드 작업을 수행하려면 필수 권한이 있어야 합니다. 버킷 정책 또는 IAM ID 기반 정책을 사용하여 IAM 보안 주체에 이러한 작업을 수행할 권한을 부여할 수 있습니다. 다음 테이블에는 여러 멀티파트 업로드 작업에 대한 필수 권한이 나와 있습니다.

Initiator 요소를 통해 멀티파트 업로드의 이니시에이터를 식별할 수 있습니다. 이니시에이터가 AWS 계정일 경우 이 요소는 Owner 요소와 동일한 정보를 제공합니다. 시작한 사용자가 IAM 사용자일 경우 이 요소는 사용자 ARN 및 표시 이름을 제공합니다.

작업 필수 권한

멀티파트 업로드 생성

멀티파트 업로드를 생성하려면 디렉터리 버킷에 대해 s3express:CreateSession 작업을 수행할 수 있어야 합니다.

멀티파트 업로드 시작

멀티파트 업로드를 시작하려면 디렉터리 버킷에 대해 s3express:CreateSession 작업을 수행할 수 있어야 합니다.

부분 업로드

부분을 업로드하려면 디렉터리 버킷에 대해 s3express:CreateSession 작업을 수행할 수 있어야 합니다.

이니시에이터가 부분을 업로드하려면 버킷 소유자는 이니시에이터가 디렉터리 버킷에 대한 s3express:CreateSession 작업을 수행하도록 허용해야 합니다.

부분 업로드(복사)

부분을 업로드하려면 디렉터리 버킷에 대해 s3express:CreateSession 작업을 수행할 수 있어야 합니다.

버킷 소유자는 객체의 멀티파트 업로드를 시작하는 사용자에게 s3express:CreateSession 작업을 수행할 수 있는 권한을 부여해야 합니다.

멀티파트 업로드 완료

멀티파트 업로드를 완료하려면 디렉터리 버킷에 대해 s3express:CreateSession 작업을 수행할 수 있어야 합니다.

버킷 소유자는 이니시에이터가 멀티파트 업로드를 완료할 수 있도록 객체에 대해 s3express:CreateSession 작업을 수행할 수 있는 권한을 부여해야 합니다.

멀티파트 업로드 중단

멀티파트 업로드를 중단하려면 객체에 대해 s3express:CreateSession 작업을 수행할 수 있어야 합니다.

멀티파트 업로드를 중단하려면 이니시에이터에게 s3express:CreateSession 작업을 수행할 수 있는 명시적 허용 액세스 권한을 부여해야 합니다.

부분 나열

멀티파트 업로드의 부분을 나열하려면 디렉터리 버킷에 대해 s3express:CreateSession 작업을 수행할 수 있어야 합니다.

진행 중인 멀티파트 업로드 나열

버킷에 대해 진행 중인 멀티파트 업로드를 나열하려면 버킷에 대해 s3:ListBucketMultipartUploads 작업을 수행할 수 있어야 합니다.

멀티파트 업로드를 위한 API 작업 지원

Amazon Simple Storage Service API 참조의 다음 섹션에서는 멀티파트 업로드를 위한 Amazon S3 REST API 작업에 대해 설명합니다.

예제

멀티파트 업로드를 사용하여 디렉터리 버킷의 S3 Express One Zone에 객체를 업로드하려면 다음 예제를 참조하세요.

멀티파트 업로드 생성

다음 예시는 멀티파트 업로드를 만드는 방법을 보여 줍니다.

SDK for Java 2.x
/** * This method creates a multipart upload request that generates a unique upload ID that is used to track * all the upload parts * * @param s3 * @param bucketName - for example, 'doc-example-bucket--use1-az4--x-s3' * @param key * @return */ private static String createMultipartUpload(S3Client s3, String bucketName, String key) { CreateMultipartUploadRequest createMultipartUploadRequest = CreateMultipartUploadRequest.builder() .bucket(bucketName) .key(key) .build(); String uploadId = null; try { CreateMultipartUploadResponse response = s3.createMultipartUpload(createMultipartUploadRequest); uploadId = response.uploadId(); } catch (S3Exception e) { System.err.println(e.awsErrorDetails().errorMessage()); System.exit(1); } return uploadId;
SDK for Python
def create_multipart_upload(s3_client, bucket_name, key_name): ''' Create a multipart upload to a directory bucket :param s3_client: boto3 S3 client :param bucket_name: The destination bucket for the multipart upload :param key_name: The key name for the object to be uploaded :return: The UploadId for the multipart upload if created successfully, else None ''' try: mpu = s3_client.create_multipart_upload(Bucket = bucket_name, Key = key_name) return mpu['UploadId'] except ClientError as e: logging.error(e) return None

이 예시는 AWS CLI를 사용하여 디렉터리 버킷에 대한 멀티파트 업로드를 생성하는 방법을 보여 줍니다. 이 명령은 KEY_NAME 객체에 대해 디렉터리 버킷 bucket-base-name--azid--x-s3에 멀티파트 업로드를 시작합니다. 명령을 사용하려면 사용자 입력 자리 표시자를 사용자의 정보로 대체합니다.

aws s3api create-multipart-upload --bucket bucket-base-name--azid--x-s3 --key KEY_NAME

자세한 내용은 AWS Command Line Interface의 create-multipart-upload를 참조하세요.

멀티파트 업로드의 부분 업로드

다음 코드 예시는 멀티파트 업로드의 일부를 업로드하는 방법을 보여 줍니다.

SDK for Java 2.x

다음 예시는 SDK for Java 2.x를 사용하여 단일 객체를 여러 부분으로 나눈 다음 디렉터리 버킷에 업로드하는 방법을 보여 줍니다.

/** * This method creates part requests and uploads individual parts to S3 and then returns all the completed parts * * @param s3 * @param bucketName * @param key * @param uploadId * @throws IOException */ private static ListCompletedPartmultipartUpload(S3Client s3, String bucketName, String key, String uploadId, String filePath) throws IOException { int partNumber = 1; ListCompletedPart completedParts = new ArrayList<>(); ByteBuffer bb = ByteBuffer.allocate(1024 * 1024 * 5); // 5 MB byte buffer // read the local file, breakdown into chunks and process try (RandomAccessFile file = new RandomAccessFile(filePath, "r")) { long fileSize = file.length(); int position = 0; while (position < fileSize) { file.seek(position); int read = file.getChannel().read(bb); bb.flip(); // Swap position and limit before reading from the buffer. UploadPartRequest uploadPartRequest = UploadPartRequest.builder() .bucket(bucketName) .key(key) .uploadId(uploadId) .partNumber(partNumber) .build(); UploadPartResponse partResponse = s3.uploadPart( uploadPartRequest, RequestBody.fromByteBuffer(bb)); CompletedPart part = CompletedPart.builder() .partNumber(partNumber) .eTag(partResponse.eTag()) .build(); completedParts.add(part); bb.clear(); position += read; partNumber++; } } catch (IOException e) { throw e; } return completedParts; }
SDK for Python

다음 예시는 SDK for Python을 사용하여 단일 객체를 여러 부분으로 나눈 다음 디렉터리 버킷에 업로드하는 방법을 보여 줍니다.

def multipart_upload(s3_client, bucket_name, key_name, mpu_id, part_size): ''' Break up a file into multiple parts and upload those parts to a directory bucket :param s3_client: boto3 S3 client :param bucket_name: Destination bucket for the multipart upload :param key_name: Key name for object to be uploaded and for the local file that's being uploaded :param mpu_id: The UploadId returned from the create_multipart_upload call :param part_size: The size parts that the object will be broken into, in bytes. Minimum 5 MiB, Maximum 5 GiB. There is no minimum size for the last part of your multipart upload. :return: part_list for the multipart upload if all parts are uploaded successfully, else None ''' part_list = [] try: with open(key_name, 'rb') as file: part_counter = 1 while True: file_part = file.read(part_size) if not len(file_part): break upload_part = s3_client.upload_part( Bucket = bucket_name, Key = key_name, UploadId = mpu_id, Body = file_part, PartNumber = part_counter ) part_list.append({'PartNumber': part_counter, 'ETag': upload_part['ETag']}) part_counter += 1 except ClientError as e: logging.error(e) return None return part_list

이 예시는 AWS CLI를 사용하여 단일 객체를 여러 부분으로 나눈 다음 디렉터리 버킷에 업로드하는 방법을 보여 줍니다. 명령을 사용하려면 사용자 입력 자리 표시자를 사용자의 정보로 대체합니다.

aws s3api upload-part --bucket bucket-base-name--azid--x-s3 --key KEY_NAME --part-number 1 --body LOCAL_FILE_NAME --upload-id "AS_mgt9RaQE9GEaifATue15dAAAAAAAAAAEMAAAAAAAAADQwNzI4MDU0MjUyMBYAAAAAAAAAAA0AAAAAAAAAAAH2AfYAAAAAAAAEBSD0WBKMAQAAAABneY9yBVsK89iFkvWdQhRCcXohE8RbYtc9QvBOG8tNpA"

자세한 내용은 AWS Command Line Interface의 upload-part를 참조하세요.

멀티파트 업로드 완료

다음 예시는 멀티파트 업로드를 완료하는 방법을 보여 줍니다.

SDK for Java 2.x

다음 예시는 SDK for Java 2.x를 사용하여 멀티파트 업로드를 완료하는 방법을 보여 줍니다.

/** * This method completes the multipart upload request by collating all the upload parts * @param s3 * @param bucketName - for example, 'doc-example-bucket--usw2-az1--x-s3' * @param key * @param uploadId * @param uploadParts */ private static void completeMultipartUpload(S3Client s3, String bucketName, String key, String uploadId, ListCompletedPart uploadParts) { CompletedMultipartUpload completedMultipartUpload = CompletedMultipartUpload.builder() .parts(uploadParts) .build(); CompleteMultipartUploadRequest completeMultipartUploadRequest = CompleteMultipartUploadRequest.builder() .bucket(bucketName) .key(key) .uploadId(uploadId) .multipartUpload(completedMultipartUpload) .build(); s3.completeMultipartUpload(completeMultipartUploadRequest); } public static void multipartUploadTest(S3Client s3, String bucketName, String key, String localFilePath) { System.out.println("Starting multipart upload for: " + key); try { String uploadId = createMultipartUpload(s3, bucketName, key); System.out.println(uploadId); ListCompletedPart parts = multipartUpload(s3, bucketName, key, uploadId, localFilePath); completeMultipartUpload(s3, bucketName, key, uploadId, parts); System.out.println("Multipart upload completed for: " + key); } catch (Exception e) { System.err.println(e.getMessage()); System.exit(1); } }
SDK for Python

다음 예시는 SDK for Python을 사용하여 멀티파트 업로드를 완료하는 방법을 보여 줍니다.

def complete_multipart_upload(s3_client, bucket_name, key_name, mpu_id, part_list): ''' Completes a multipart upload to a directory bucket :param s3_client: boto3 S3 client :param bucket_name: The destination bucket for the multipart upload :param key_name: The key name for the object to be uploaded :param mpu_id: The UploadId returned from the create_multipart_upload call :param part_list: The list of uploaded part numbers with their associated ETags :return: True if the multipart upload was completed successfully, else False ''' try: s3_client.complete_multipart_upload( Bucket = bucket_name, Key = key_name, UploadId = mpu_id, MultipartUpload = { 'Parts': part_list } ) except ClientError as e: logging.error(e) return False return True if __name__ == '__main__': MB = 1024 ** 2 region = 'us-west-2' bucket_name = 'BUCKET_NAME' key_name = 'OBJECT_NAME' part_size = 10 * MB s3_client = boto3.client('s3', region_name = region) mpu_id = create_multipart_upload(s3_client, bucket_name, key_name) if mpu_id is not None: part_list = multipart_upload(s3_client, bucket_name, key_name, mpu_id, part_size) if part_list is not None: if complete_multipart_upload(s3_client, bucket_name, key_name, mpu_id, part_list): print (f'{key_name} successfully uploaded through a ultipart upload to {bucket_name}') else: print (f'Could not upload {key_name} hrough a multipart upload to {bucket_name}')

이 예시는 AWS CLI을 사용하여 디렉터리 버킷에 대한 멀티파트 업로드를 완료하는 방법을 보여 줍니다. 명령을 사용하려면 사용자 입력 자리 표시자를 사용자의 정보로 대체합니다.

aws s3api complete-multipart-upload --bucket bucket-base-name--azid--x-s3 --key KEY_NAME --upload-id "AS_mgt9RaQE9GEaifATue15dAAAAAAAAAAEMAAAAAAAAADQwNzI4MDU0MjUyMBYAAAAAAAAAAA0AAAAAAAAAAAH2AfYAAAAAAAAEBSD0WBKMAQAAAABneY9yBVsK89iFkvWdQhRCcXohE8RbYtc9QvBOG8tNpA" --multipart-upload file://parts.json

이 예시는 전체 파일로 리어셈블해야 하는 멀티파트 업로드의 부분을 설명하는 JSON 구조를 사용합니다. 이 예시에서는 file:// 접두사를 사용하여 parts라는 로컬 폴더에 있는 파일에서 JSON 구조를 로드합니다.

parts.json:

parts.json { "Parts": [ { "ETag": "6b78c4a64dd641a58dac8d9258b88147", "PartNumber": 1 } ] }

자세한 내용은 AWS Command Line Interface의 complete-multipart-upload를 참조하세요.

멀티파트 업로드 중단

다음 예시는 멀티파트 업로드를 중단하는 방법을 보여 줍니다.

SDK for Java 2.x

다음 예시는 SDK for Java 2.x를 사용하여 멀티파트 업로드를 중단하는 방법을 보여 줍니다.

public static void abortMultiPartUploads( S3Client s3, String bucketName ) { try { ListMultipartUploadsRequest listMultipartUploadsRequest = ListMultipartUploadsRequest.builder() .bucket(bucketName) .build(); ListMultipartUploadsResponse response = s3.listMultipartUploads(listMultipartUploadsRequest); ListMultipartUpload uploads = response.uploads(); AbortMultipartUploadRequest abortMultipartUploadRequest; for (MultipartUpload upload: uploads) { abortMultipartUploadRequest = AbortMultipartUploadRequest.builder() .bucket(bucketName) .key(upload.key()) .uploadId(upload.uploadId()) .build(); s3.abortMultipartUpload(abortMultipartUploadRequest); } } catch (S3Exception e) { System.err.println(e.getMessage()); System.exit(1); } }
SDK for Python

다음 예시는 SDK for Python을 사용하여 멀티파트 업로드를 중단하는 방법을 보여 줍니다.

import logging import boto3 from botocore.exceptions import ClientError def abort_multipart_upload(s3_client, bucket_name, key_name, upload_id): ''' Aborts a partial multipart upload in a directory bucket. :param s3_client: boto3 S3 client :param bucket_name: Bucket where the multipart upload was initiated - for example, 'doc-example-bucket--usw2-az1--x-s3' :param key_name: Name of the object for which the multipart upload needs to be aborted :param upload_id: Multipart upload ID for the multipart upload to be aborted :return: True if the multipart upload was successfully aborted, False if not ''' try: s3_client.abort_multipart_upload( Bucket = bucket_name, Key = key_name, UploadId = upload_id ) except ClientError as e: logging.error(e) return False return True if __name__ == '__main__': region = 'us-west-2' bucket_name = 'BUCKET_NAME' key_name = 'KEY_NAME' upload_id = 'UPLOAD_ID' s3_client = boto3.client('s3', region_name = region) if abort_multipart_upload(s3_client, bucket_name, key_name, upload_id): print (f'Multipart upload for object {key_name} in {bucket_name} bucket has been aborted') else: print (f'Unable to abort multipart upload for object {key_name} in {bucket_name} bucket')

다음 예시는 AWS CLI를 사용하여 멀티파트 업로드를 중단하는 방법을 보여 줍니다. 명령을 사용하려면 사용자 입력 자리 표시자를 사용자의 정보로 대체합니다.

aws s3api abort-multipart-upload --bucket bucket-base-name--azid--x-s3 --key KEY_NAME --upload-id "AS_mgt9RaQE9GEaifATue15dAAAAAAAAAAEMAAAAAAAAADQwNzI4MDU0MjUyMBYAAAAAAAAAAA0AAAAAAAAAAAH2AfYAAAAAAAAEAX5hFw-MAQAAAAB0OxUFeA7LTbWWFS8WYwhrxDxTIDN-pdEEq_agIHqsbg"

자세한 내용은 AWS Command Line Interface의 abort-multipart-upload를 참조하세요.

멀티파트 업로드 복사 작업 생성

다음 예시는 멀티파트 업로드를 사용하여 버킷 간 객체를 복사하는 방법을 보여 줍니다.

SDK for Java 2.x

다음 예시는 SDK for Java 2.x를 통해 멀티파트 업로드를 사용하여 프로그래밍 방식으로 버킷의 객체를 다른 버킷으로 복사하는 방법을 보여 줍니다.

/** * This method creates a multipart upload request that generates a unique upload ID that is used to track * all the upload parts. * * @param s3 * @param bucketName * @param key * @return */ private static String createMultipartUpload(S3Client s3, String bucketName, String key) { CreateMultipartUploadRequest createMultipartUploadRequest = CreateMultipartUploadRequest.builder() .bucket(bucketName) .key(key) .build(); String uploadId = null; try { CreateMultipartUploadResponse response = s3.createMultipartUpload(createMultipartUploadRequest); uploadId = response.uploadId(); } catch (S3Exception e) { System.err.println(e.awsErrorDetails().errorMessage()); System.exit(1); } return uploadId; } /** * Creates copy parts based on source object size and copies over individual parts * * @param s3 * @param sourceBucket * @param sourceKey * @param destnBucket * @param destnKey * @param uploadId * @return * @throws IOException */ public static ListCompletedPart multipartUploadCopy(S3Client s3, String sourceBucket, String sourceKey, String destnBucket, String destnKey, String uploadId) throws IOException { // Get the object size to track the end of the copy operation. HeadObjectRequest headObjectRequest = HeadObjectRequest .builder() .bucket(sourceBucket) .key(sourceKey) .build(); HeadObjectResponse response = s3.headObject(headObjectRequest); Long objectSize = response.contentLength(); System.out.println("Source Object size: " + objectSize); // Copy the object using 20 MB parts. long partSize = 20 * 1024 * 1024; long bytePosition = 0; int partNum = 1; ListCompletedPart completedParts = new ArrayList<>(); while (bytePosition < objectSize) { // The last part might be smaller than partSize, so check to make sure // that lastByte isn't beyond the end of the object. long lastByte = Math.min(bytePosition + partSize - 1, objectSize - 1); System.out.println("part no: " + partNum + ", bytePosition: " + bytePosition + ", lastByte: " + lastByte); // Copy this part. UploadPartCopyRequest req = UploadPartCopyRequest.builder() .uploadId(uploadId) .sourceBucket(sourceBucket) .sourceKey(sourceKey) .destinationBucket(destnBucket) .destinationKey(destnKey) .copySourceRange("bytes="+bytePosition+"-"+lastByte) .partNumber(partNum) .build(); UploadPartCopyResponse res = s3.uploadPartCopy(req); CompletedPart part = CompletedPart.builder() .partNumber(partNum) .eTag(res.copyPartResult().eTag()) .build(); completedParts.add(part); partNum++; bytePosition += partSize; } return completedParts; } public static void multipartCopyUploadTest(S3Client s3, String srcBucket, String srcKey, String destnBucket, String destnKey) { System.out.println("Starting multipart copy for: " + srcKey); try { String uploadId = createMultipartUpload(s3, destnBucket, destnKey); System.out.println(uploadId); ListCompletedPart parts = multipartUploadCopy(s3, srcBucket, srcKey,destnBucket, destnKey, uploadId); completeMultipartUpload(s3, destnBucket, destnKey, uploadId, parts); System.out.println("Multipart copy completed for: " + srcKey); } catch (Exception e) { System.err.println(e.getMessage()); System.exit(1); } }
SDK for Python

다음 예시는 SDK for Python을 통해 멀티파트 업로드를 사용하여 프로그래밍 방식으로 버킷의 객체를 다른 버킷으로 복사하는 방법을 보여 줍니다.

import logging import boto3 from botocore.exceptions import ClientError def head_object(s3_client, bucket_name, key_name): ''' Returns metadata for an object in a directory bucket :param s3_client: boto3 S3 client :param bucket_name: Bucket that contains the object to query for metadata :param key_name: Key name to query for metadata :return: Metadata for the specified object if successful, else None ''' try: response = s3_client.head_object( Bucket = bucket_name, Key = key_name ) return response except ClientError as e: logging.error(e) return None def create_multipart_upload(s3_client, bucket_name, key_name): ''' Create a multipart upload to a directory bucket :param s3_client: boto3 S3 client :param bucket_name: Destination bucket for the multipart upload :param key_name: Key name of the object to be uploaded :return: UploadId for the multipart upload if created successfully, else None ''' try: mpu = s3_client.create_multipart_upload(Bucket = bucket_name, Key = key_name) return mpu['UploadId'] except ClientError as e: logging.error(e) return None def multipart_copy_upload(s3_client, source_bucket_name, key_name, target_bucket_name, mpu_id, part_size): ''' Copy an object in a directory bucket to another bucket in multiple parts of a specified size :param s3_client: boto3 S3 client :param source_bucket_name: Bucket where the source object exists :param key_name: Key name of the object to be copied :param target_bucket_name: Destination bucket for copied object :param mpu_id: The UploadId returned from the create_multipart_upload call :param part_size: The size parts that the object will be broken into, in bytes. Minimum 5 MiB, Maximum 5 GiB. There is no minimum size for the last part of your multipart upload. :return: part_list for the multipart copy if all parts are copied successfully, else None ''' part_list = [] copy_source = { 'Bucket': source_bucket_name, 'Key': key_name } try: part_counter = 1 object_size = head_object(s3_client, source_bucket_name, key_name) if object_size is not None: object_size = object_size['ContentLength'] while (part_counter - 1) * part_size <object_size: bytes_start = (part_counter - 1) * part_size bytes_end = (part_counter * part_size) - 1 upload_copy_part = s3_client.upload_part_copy ( Bucket = target_bucket_name, CopySource = copy_source, CopySourceRange = f'bytes={bytes_start}-{bytes_end}', Key = key_name, PartNumber = part_counter, UploadId = mpu_id ) part_list.append({'PartNumber': part_counter, 'ETag': upload_copy_part['CopyPartResult']['ETag']}) part_counter += 1 except ClientError as e: logging.error(e) return None return part_list def complete_multipart_upload(s3_client, bucket_name, key_name, mpu_id, part_list): ''' Completes a multipart upload to a directory bucket :param s3_client: boto3 S3 client :param bucket_name: Destination bucket for the multipart upload :param key_name: Key name of the object to be uploaded :param mpu_id: The UploadId returned from the create_multipart_upload call :param part_list: List of uploaded part numbers with associated ETags :return: True if the multipart upload was completed successfully, else False ''' try: s3_client.complete_multipart_upload( Bucket = bucket_name, Key = key_name, UploadId = mpu_id, MultipartUpload = { 'Parts': part_list } ) except ClientError as e: logging.error(e) return False return True if __name__ == '__main__': MB = 1024 ** 2 region = 'us-west-2' source_bucket_name = 'SOURCE_BUCKET_NAME' target_bucket_name = 'TARGET_BUCKET_NAME' key_name = 'KEY_NAME' part_size = 10 * MB s3_client = boto3.client('s3', region_name = region) mpu_id = create_multipart_upload(s3_client, target_bucket_name, key_name) if mpu_id is not None: part_list = multipart_copy_upload(s3_client, source_bucket_name, key_name, target_bucket_name, mpu_id, part_size) if part_list is not None: if complete_multipart_upload(s3_client, target_bucket_name, key_name, mpu_id, part_list): print (f'{key_name} successfully copied through multipart copy from {source_bucket_name} to {target_bucket_name}') else: print (f'Could not copy {key_name} through multipart copy from {source_bucket_name} to {target_bucket_name}')

다음 예시는 AWS CLI를 통해 멀티파트 업로드를 사용하여 프로그래밍 방식으로 버킷의 객체를 디렉터리 버킷으로 복사하는 방법을 보여 줍니다. 명령을 사용하려면 사용자 입력 자리 표시자를 사용자의 정보로 대체합니다.

aws s3api upload-part-copy --bucket bucket-base-name--azid--x-s3 --key TARGET_KEY_NAME --copy-source SOURCE_BUCKET_NAME/SOURCE_KEY_NAME --part-number 1 --upload-id "AS_mgt9RaQE9GEaifATue15dAAAAAAAAAAEMAAAAAAAAADQwNzI4MDU0MjUyMBYAAAAAAAAAAA0AAAAAAAAAAAH2AfYAAAAAAAAEBnJ4cxKMAQAAAABiNXpOFVZJ1tZcKWib9YKE1C565_hCkDJ_4AfCap2svg"

자세한 내용은 AWS Command Line Interface의 upload-part-copy를 참조하세요.

진행 중인 멀티파트 업로드 나열

AWS SDK 또는 AWS CLI를 사용하여 디렉터리 버킷에 대해 진행 중인 멀티파트 업로드를 나열할 수 있습니다.

SDK for Java 2.x

다음 예시는 SDK for Java 2.x를 사용하여 진행 중인(완료되지 않은) 멀티파트 업로드를 나열하는 방법을 보여 줍니다.

public static void listMultiPartUploads( S3Client s3, String bucketName) { try { ListMultipartUploadsRequest listMultipartUploadsRequest = ListMultipartUploadsRequest.builder() .bucket(bucketName) .build(); ListMultipartUploadsResponse response = s3.listMultipartUploads(listMultipartUploadsRequest); List MultipartUpload uploads = response.uploads(); for (MultipartUpload upload: uploads) { System.out.println("Upload in progress: Key = \"" + upload.key() + "\", id = " + upload.uploadId()); } } catch (S3Exception e) { System.err.println(e.getMessage()); System.exit(1); } }
SDK for Python

다음 예시는 SDK for Python을 사용하여 진행 중인(완료되지 않은) 멀티파트 업로드를 나열하는 방법을 보여 줍니다.

import logging import boto3 from botocore.exceptions import ClientError def list_multipart_uploads(s3_client, bucket_name): ''' List any incomplete multipart uploads in a directory bucket in e specified gion :param s3_client: boto3 S3 client :param bucket_name: Bucket to check for incomplete multipart uploads :return: List of incomplete multipart uploads if there are any, None if not ''' try: response = s3_client.list_multipart_uploads(Bucket = bucket_name) if 'Uploads' in response.keys(): return response['Uploads'] else: return None except ClientError as e: logging.error(e) if __name__ == '__main__': bucket_name = 'BUCKET_NAME' region = 'us-west-2' s3_client = boto3.client('s3', region_name = region) multipart_uploads = list_multipart_uploads(s3_client, bucket_name) if multipart_uploads is not None: print (f'There are {len(multipart_uploads)} ncomplete multipart uploads for {bucket_name}') else: print (f'There are no incomplete multipart uploads for {bucket_name}')

다음 예시는 AWS CLI를 사용하여 진행 중인(완료되지 않은) 멀티파트 업로드를 나열하는 방법을 보여 줍니다. 명령을 사용하려면 사용자 입력 자리 표시자를 사용자의 정보로 대체합니다.

aws s3api list-multipart-uploads --bucket bucket-base-name--azid--x-s3

자세한 내용은 AWS Command Line Interface의 list-multipart-uploads를 참조하세요.

멀티파트 업로드의 부분 나열

다음 예시는 디렉터리 버킷에 대한 멀티파트 업로드의 부분을 나열하는 방법을 보여 줍니다.

SDK for Java 2.x

다음 예시는 SDK for Java 2.x를 사용하여 디렉터리 버킷에 대한 멀티파트 업로드의 부분을 나열하는 방법을 보여 줍니다.

public static void listMultiPartUploadsParts( S3Client s3, String bucketName, String objKey, String uploadID) { try { ListPartsRequest listPartsRequest = ListPartsRequest.builder() .bucket(bucketName) .uploadId(uploadID) .key(objKey) .build(); ListPartsResponse response = s3.listParts(listPartsRequest); ListPart parts = response.parts(); for (Part part: parts) { System.out.println("Upload in progress: Part number = \"" + part.partNumber() + "\", etag = " + part.eTag()); } } catch (S3Exception e) { System.err.println(e.getMessage()); System.exit(1); } }
SDK for Python

다음 예시는 SDK for Python을 사용하여 디렉터리 버킷에 대한 멀티파트 업로드의 부분을 나열하는 방법을 보여 줍니다.

import logging import boto3 from botocore.exceptions import ClientError def list_parts(s3_client, bucket_name, key_name, upload_id): ''' Lists the parts that have been uploaded for a specific multipart upload to a directory bucket. :param s3_client: boto3 S3 client :param bucket_name: Bucket that multipart uploads parts have been uploaded to :param key_name: Name of the object that has parts uploaded :param upload_id: Multipart upload ID that the parts are associated with :return: List of parts associated with the specified multipart upload, None if there are no parts ''' parts_list = [] next_part_marker = '' continuation_flag = True try: while continuation_flag: if next_part_marker == '': response = s3_client.list_parts( Bucket = bucket_name, Key = key_name, UploadId = upload_id ) else: response = s3_client.list_parts( Bucket = bucket_name, Key = key_name, UploadId = upload_id, NextPartMarker = next_part_marker ) if 'Parts' in response: for part in response['Parts']: parts_list.append(part) if response['IsTruncated']: next_part_marker = response['NextPartNumberMarker'] else: continuation_flag = False else: continuation_flag = False return parts_list except ClientError as e: logging.error(e) return None if __name__ == '__main__': region = 'us-west-2' bucket_name = 'BUCKET_NAME' key_name = 'KEY_NAME' upload_id = 'UPLOAD_ID' s3_client = boto3.client('s3', region_name = region) parts_list = list_parts(s3_client, bucket_name, key_name, upload_id) if parts_list is not None: print (f'{key_name} has {len(parts_list)} parts uploaded to {bucket_name}') else: print (f'There are no multipart uploads with that upload ID for {bucket_name} bucket')

다음 예시는 AWS CLI를 사용하여 디렉터리 버킷에 대한 멀티파트 업로드의 부분을 나열하는 방법을 보여 줍니다. 명령을 사용하려면 사용자 입력 자리 표시자를 사용자의 정보로 대체합니다.

aws s3api list-parts --bucket bucket-base-name--azid--x-s3 --key KEY_NAME --upload-id "AS_mgt9RaQE9GEaifATue15dAAAAAAAAAAEMAAAAAAAAADQwNzI4MDU0MjUyMBYAAAAAAAAAAA0AAAAAAAAAAAH2AfYAAAAAAAAEBSD0WBKMAQAAAABneY9yBVsK89iFkvWdQhRCcXohE8RbYtc9QvBOG8tNpA"

자세한 내용은 AWS Command Line Interface의 list-parts를 참조하세요.