ディレクトリバケットでのマルチパートアップロードの使用
マルチパートアップロードプロセスを使用すると、単一のオブジェクトをパートのセットとしてアップロードすることができます。各パートは、オブジェクトのデータの連続する部分です。これらのオブジェクトパートは、任意の順序で個別にアップロードできます。いずれかのパートの送信が失敗すると、他のパートに影響を与えることなくそのパートを再送することができます。オブジェクトのすべてのパートがアップロードされたら、Amazon S3 はこれらのパートを組み立ててオブジェクトを作成します。通常、オブジェクトサイズが 100 MB 以上の場合は、単一のオペレーションでオブジェクトをアップロードする代わりに、マルチパートアップロードを使用することを考慮してください。
マルチパートアップロードの使用には、次の利点があります。
-
スループットの向上 − パートを並列にアップロードすることで、スループットを向上させることができます。
-
ネットワーク問題からの迅速な回復 − パートサイズが小さいほど、ネットワークエラーが原因で失敗したアップロードを再開する際の影響を最小限に抑えることができます。
-
オブジェクトのアップロードの一時停止と再開 – オブジェクトの複数のパートを徐々にアップロードできます。マルチパートアップロードをいったん開始すると、終了期限はありません。マルチパートアップロードを明示的に完了または中止する必要があります。
-
オブジェクトの最終的なサイズが不明な状態でアップロードを開始 – オブジェクトの作成中でもアップロードを開始できます。
次の方法でマルチパートアップロードを使用することをお勧めします。
-
安定した高帯域幅ネットワーク経由で大きなオブジェクトをアップロードする場合は、複数スレッドのパフォーマンスのためにオブジェクトパートを並行してアップロードすることで、マルチパートアップロードを使用して利用可能な帯域幅を最大限に活用します。
-
むらがあるネットワークでアップロードを実行する場合は、マルチパートアップロードを使用して、アップロードの再開を回避することで、ネットワークエラーに対する回復性を高めます。マルチパートアップロードを使用するときには、アップロード中に中断されたパートのアップロードを再試行するだけで済みます。最初からオブジェクトのアップロードを再開する必要はありません。
マルチパートアップロードを使用してディレクトリバケットの Amazon S3 Express One Zone ストレージクラスにオブジェクトをアップロードする場合、マルチパートアップロードプロセスは、マルチパートアップロードを使用して汎用バケットにオブジェクトをアップロードするプロセスと似ています。ただし、重要な相違点がいくつかあります。
マルチパートアップロードを使用して S3 Express One Zone ゾーンにオブジェクトをアップロードする方法の詳細については、以降のトピックを参照してください。
マルチパートアップロードのプロセス
マルチパートアップロードは次の 3 ステップのプロセスです。
Amazon S3 の側では、マルチパートアップロードの完了リクエストを受け取ると同時に、アップロードされたパートからオブジェクトを構築します。構築されたオブジェクトへは、バケット内の他のオブジェクトと同じようにアクセスできます。
マルチパートアップロードの開始
リクエストを送信すると、アップロード ID を含むレスポンスが 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 と AWS KMS キーによるサーバー側の暗号化 (SSE-KMS) がサポートされています。詳細については、「S3 Express One Zone でのデータ保護と暗号化」を参照してください。
マルチパートアップロードの完了
マルチパートアップロードを完了すると、パート番号に基づいて昇順に連結されたオブジェクトが Amazon S3 によって作成されます。完了リクエストが正常に処理されると、個々のパートはなくなります。
「マルチパートアップロードの完了」リクエストには、アップロード ID と、パート番号およびそれに対応する ETag 値の両方のリストが含まれている必要があります。Amazon S3 からのレスポンスには、結合されるオブジェクトデータを一意に識別する ETag が含まれます。この ETag は、オブジェクトデータの MD5 ハッシュであるとは限りません。
マルチパートアップロードのリスト化
特定のマルチパートアップロードのパートや、進行中のすべてのマルチパートアップロードをリスト表示できます。パートのリストオペレーションでは、特定のマルチパートアップロードについて既にアップロードしたパートの情報が返されます。パートのリストリクエストを送信するたびに、指定したマルチパートアップロードのパート情報 (最大で 1,000 個のパート) が Amazon S3 から返されます。マルチパートアップロードに 1,000 を超えるパートが含まれる場合、すべてのパートを取得するにはパートのリストリクエストを追加で送信する必要があります。
返されるパートのリストには、アップロードが完了していないパートは含まれていません。マルチパートアップロードの一覧表示オペレーションを使用すると、進行中のマルチパートアップロードのリストを取得できます。
進行中のマルチパートアップロードとは、開始されているものの、まだ完了または中止されていないアップロードを意味します。各リクエストに最大 1,000 個のマルチパートアップロードが返されます。進行中のマルチパートアップロードが 1,000 個を超える場合、残りのマルチパートアップロードを取得するには、リクエストを追加で送信する必要があります。返されたリストは確認の目的でのみ使用してください。マルチパートアップロードの完了リクエストを送信するときに、このリストの結果を使用しないでください。代わりに、パートのアップロード時に指定したパート番号と、それに対応する、Amazon S3 から返される ETag 値の独自のリストを維持しておいてください。
マルチパートアップロードの一覧の詳細については、「Amazon Simple Storage Service API リファレンス」の「ListParts」を参照してください。
マルチパートアップロードオペレーションを使用したチェックサム
オブジェクトをアップロードする際、オブジェクトの整合性を確認するためのチェックサムアルゴリズムを指定できます。MD5 はディレクトリバケットではサポートされていません。次のセキュアハッシュアルゴリズム (SHA) または巡回冗長検査 (CRC) のデータ整合性チェックアルゴリズムのいずれかを指定できます。
-
CRC32
-
CRC32C
-
SHA-1
-
SHA-256
GetObject
または HeadObject
を使用することで、Amazon S3 REST API または AWS SDK を使用して、個々のパートのチェックサム値を取得できます。まだ処理中のマルチパートアップロードの個々の部分のチェックサム値を取得したい場合は、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 にオブジェクトをアップロードするには、次の例を参照してください。
マルチパートアップロードの作成
ディレクトリバケットの場合、CreateMultipartUpload
オペレーションと UploadPartCopy
オペレーションを実行するときに、バケットのデフォルトの暗号化で必要な暗号化設定を使用し、CreateMultipartUpload
リクエストで指定したリクエストヘッダーが送信先バケットのデフォルトの暗号化設定と一致する必要があります。
次の例は、マルチパートアップロードの作成方法を示しています。
- 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 ListCompletedPart
multipartUpload(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」を参照してください。
マルチパートアップロードのコピーオペレーションの作成
SSE-KMS を使用してディレクトリバケット内の新しいオブジェクトパーツコピーを暗号化するには、KMS キー (特にカスタマーマネージドキー) を使用してディレクトリバケットのデフォルトの暗号化設定として SSE-KMS を指定する必要があります。AWS マネージドキー (aws/s3
) はサポートされていません。SSE-KMS 設定では、バケットの存続期間中、ディレクトリバケットごとに 1 つのカスタマーマネージドキーしかサポートできません。SSE-KMS のカスタマーマネージドキーを指定した後は、バケットの SSE-KMS 設定のカスタマーマネージドキーを上書きすることはできません。UploadPartCopy リクエストヘッダーで SSE-KMS を使用した新しいオブジェクトパートコピーのサーバー側の暗号化設定を指定することはできません。また、CreateMultipartUpload
リクエストで指定するリクエストヘッダーは、送信先バケットのデフォルトの暗号化設定と一致する必要があります。
SSE-KMS で暗号化されたオブジェクトを UploadPartCopy 経由で汎用バケットからディレクトリバケットにコピーする場合、ディレクトリバケットから汎用バケットにコピーする場合、またはディレクトリバケット間でコピーする場合、S3 バケットキーはサポートされません。この場合、KMS で暗号化されたオブジェクトに対してコピーリクエストが実行されるたびに、Amazon S3 は AWS KMS を呼び出します。
次の例は、マルチパートアップロードを使用して、あるバケットから別のバケットにオブジェクトをコピーする方法を示しています。
- 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」を参照してください。