マルチパートアップロードでは、大容量のオブジェクトを複数の小さなフラグメントに分割し、それぞれを独立してアップロードした後、単一のオブジェクトとして結合します。5 GB を超えるオブジェクトや、ネットワークの中断やプログラムのクラッシュにより単一のアップロードが中断される可能性がある場合に、マルチパートアップロードを使用してください。
前提条件
作業を開始する前に、以下の項目を準備済みであることを確認してください。
OSS バケット
RAM ユーザーに
oss:PutObject権限が付与されていること。この権限には、マルチパートアップロードの全ワークフロー(InitiateMultipartUpload、UploadPart、およびCompleteMultipartUpload)が含まれます。詳細については、「RAM ユーザーへのカスタムポリシーのアタッチ」をご参照ください。OSS_ACCESS_KEY_IDおよびOSS_ACCESS_KEY_SECRET環境変数が設定されています。詳細については、「OSS SDK for Python 1.0 を使用したアクセス認証情報の設定」をご参照ください。OSS エンドポイントです。OSS と同じリージョンにある他の Alibaba Cloud サービスから OSS にアクセスする場合は、内部エンドポイントを使用します。OSS のリージョンとエンドポイントの詳細については、「リージョンとエンドポイント」をご参照ください。
OSS SDK for Python 1.0 がインストール済みです。カスタムドメインの使用や、セキュリティトークンサービス (STS) の資格情報を使用した認証など、代替構成については、「初期化」をご参照ください。
仕組み
マルチパートアップロードは、以下の 3 つのステージで構成されます。
開始 —
bucket.init_multipart_upload()を呼び出して、OSS から一意のアップロード ID を取得します。フラグメントのアップロード — 各フラグメントに対して
bucket.upload_part()を呼び出します。フラグメントは並列でアップロード可能です。完了 —
bucket.complete_multipart_upload()を呼び出して、すべてのフラグメントを単一のオブジェクトに結合します。
各フラグメント番号は、最終的なオブジェクトにおけるそのフラグメントの位置を識別します。既存のフラグメント番号を持つ新しいフラグメントをアップロードすると、以前のフラグメントが上書きされます。
データ整合性の検証
OSS は、各アップロードされたフラグメントの MD5 ハッシュを応答の ETag ヘッダーに含めます。SDK がアップロードリクエストに Content-MD5 ヘッダーを送信すると、OSS は受信データの MD5 ハッシュを計算し、Content-MD5 値と比較します。ハッシュが一致しない場合、OSS は InvalidDigest エラーコードを返します。
パートサイズの制約
| 制約 | 値 |
|---|---|
| 最小フラグメントサイズ | 100 KB |
| 最大パートサイズ | 5 GB |
| 最終フラグメント | 100 KB 未満でも可 |
安定したネットワーク環境ではフラグメントサイズを大きくして API 呼び出し回数を削減し、不安定なネットワーク環境ではフラグメントサイズを小さくして失敗したフラグメントの再送コストを低減してください。
マルチパートアップロードによるオブジェクトのアップロード
以下の例では、ローカルファイルをマルチパートアップロードでアップロードします。determine_part_size() ヘルパー関数は、ファイル全体のサイズに基づいて適切なフラグメントサイズを計算します。
# -*- coding: utf-8 -*-
import os
from oss2 import SizedFileAdapter, determine_part_size
from oss2.models import PartInfo
import oss2
from oss2.credentials import EnvironmentVariableCredentialsProvider
# 環境変数からアクセス認証情報を取得します。サンプルコードを実行する前に、OSS_ACCESS_KEY_ID および OSS_ACCESS_KEY_SECRET 環境変数が設定済みであることを確認してください。
auth = oss2.ProviderAuthV4(EnvironmentVariableCredentialsProvider())
# バケットが配置されているリージョンのエンドポイントを指定します。たとえば、バケットが中国 (杭州) リージョンにある場合、エンドポイントは https://oss-cn-hangzhou.aliyuncs.com に設定します。
endpoint = "https://oss-cn-hangzhou.aliyuncs.com"
# エンドポイントに対応するリージョン ID を指定します。例: cn-hangzhou。署名アルゴリズム V4 を使用する場合は、このパラメーターが必要です。
region = "cn-hangzhou"
# バケット名を指定します。
bucket = oss2.Bucket(auth, endpoint, "yourBucketName", region=region)
# オブジェクトの完全なパスを指定します。完全なパスにはバケット名を含めないでください。例: exampledir/exampleobject.txt。
key = 'exampledir/exampleobject.txt'
# アップロードするローカルファイルの完全なパスを指定します。例: D:\\localpath\\examplefile.txt。
filename = 'D:\\localpath\\examplefile.txt'
total_size = os.path.getsize(filename)
# determine_part_size メソッドを使用してフラグメントサイズを決定します。最小フラグメントサイズは 100 KB、最大は 5 GB です。最終フラグメントは 100 KB 未満でも構いません。この例では、フラグメントサイズを 1 MB に設定しています。
part_size = determine_part_size(total_size, preferred_size=1 * 1024 * 1024)
# マルチパートアップロードタスクを開始します。
upload_id = bucket.init_multipart_upload(key).upload_id
parts = []
# フラグメントをアップロードします。
with open(filename, 'rb') as fileobj:
part_number = 1
offset = 0
while offset < total_size:
num_to_upload = min(part_size, total_size - offset)
# SizedFileAdapter(fileobj, size) メソッドを使用して新しいオブジェクトを生成し、追加操作の開始位置を再計算します。
result = bucket.upload_part(key, upload_id, part_number,
SizedFileAdapter(fileobj, num_to_upload))
parts.append(PartInfo(part_number, result.etag))
offset += num_to_upload
part_number += 1
# マルチパートアップロードタスクを完了します。
bucket.complete_multipart_upload(key, upload_id, parts)オプションヘッダーの設定
マルチパートアップロードの開始時にヘッダーを設定して、オブジェクトのメタデータ、暗号化、ストレージクラスを制御できます。
headers = dict()
# キャッシュ動作
# headers['Cache-Control'] = 'no-cache'
# ダウンロード時のファイル名
# headers['Content-Disposition'] = 'oss_MultipartUpload.txt'
# 有効期間(ミリ秒)
# headers['Expires'] = '1000'
# 同名の既存オブジェクトの上書きを禁止(true = 上書き禁止)
# headers['x-oss-forbid-overwrite'] = 'true'
# サーバー側暗号化方式
# headers[OSS_SERVER_SIDE_ENCRYPTION] = SERVER_SIDE_ENCRYPTION_KMS
# 暗号化アルゴリズム(デフォルト: AES-256)
# headers[OSS_SERVER_SIDE_DATA_ENCRYPTION] = SERVER_SIDE_ENCRYPTION_KMS
# KMS Customer Master Key (CMK) ID
# headers[OSS_SERVER_SIDE_ENCRYPTION_KEY_ID] = '9468da86-3509-4f8d-a61e-6eab1eac****'
# ストレージクラス
# headers['x-oss-storage-class'] = oss2.BUCKET_STORAGE_CLASS_STANDARD
# オブジェクトタグ
# headers[OSS_OBJECT_TAGGING] = 'k1=v1&k2=v2&k3=v3'
upload_id = bucket.init_multipart_upload(key, headers=headers).upload_idアップロード完了時にオブジェクトのアクセス制御リスト (ACL) を設定できます。
headers = dict()
# オブジェクト ACL を非公開に設定
# headers["x-oss-object-acl"] = oss2.OBJECT_ACL_PRIVATE
bucket.complete_multipart_upload(key, upload_id, parts, headers=headers)サーバー上のフラグメント一覧によるアップロードの完了
ローカルでフラグメントをトラックする代わりに、OSS にアップロード済みのすべてのフラグメントを一覧表示させて自動的にアセンブルさせることができます。x-oss-complete-all ヘッダーを yes に設定し、parts パラメーターに None を渡します。
x-oss-complete-all:yes を指定した場合、リクエストボディを指定できません。OSS は指定されたアップロード ID でアップロードされたすべてのフラグメントを一覧表示し、フラグメント番号でソートしてアップロードを完了します。# -*- coding: utf-8 -*-
import oss2
from oss2.credentials import EnvironmentVariableCredentialsProvider
# 環境変数からアクセス認証情報を取得します。サンプルコードを実行する前に、OSS_ACCESS_KEY_ID および OSS_ACCESS_KEY_SECRET 環境変数が設定済みであることを確認してください。
auth = oss2.ProviderAuthV4(EnvironmentVariableCredentialsProvider())
# バケットが配置されているリージョンのエンドポイントを指定します。たとえば、バケットが中国 (杭州) リージョンにある場合、エンドポイントは https://oss-cn-hangzhou.aliyuncs.com に設定します。
endpoint = "https://oss-cn-hangzhou.aliyuncs.com"
# エンドポイントに対応するリージョン ID を指定します。例: cn-hangzhou。署名アルゴリズム V4 を使用する場合は、このパラメーターが必要です。
region = "cn-hangzhou"
# バケット名を指定します。
bucket = oss2.Bucket(auth, endpoint, "yourBucketName", region=region)
# オブジェクトの完全なパスを指定します。完全なパスにはバケット名を含めないでください。例: exampledir/exampleobject.txt。
key = 'exampledir/exampleobject.txt'
# アップロード ID を指定します。アップロード ID は InitiateMultipartUpload 操作の応答から取得できます。
upload_id = '0004B9894A22E5B1888A1E29F823****'
headers = dict()
# headers["x-oss-object-acl"] = oss2.OBJECT_ACL_PRIVATE
headers["x-oss-complete-all"] = 'yes'
bucket.complete_multipart_upload(key, upload_id, None, headers=headers)マルチパートアップロードのキャンセル
進行中のマルチパートアップロードをキャンセルするには、bucket.abort_multipart_upload() を呼び出します。キャンセル後、アップロード ID は無効になり、すべてのアップロード済みフラグメントが削除されます。
# -*- coding: utf-8 -*-
import os
import oss2
from oss2.credentials import EnvironmentVariableCredentialsProvider
# 環境変数からアクセス認証情報を取得します。サンプルコードを実行する前に、OSS_ACCESS_KEY_ID および OSS_ACCESS_KEY_SECRET 環境変数が設定済みであることを確認してください。
auth = oss2.ProviderAuthV4(EnvironmentVariableCredentialsProvider())
# バケットが配置されているリージョンのエンドポイントを指定します。たとえば、バケットが中国 (杭州) リージョンにある場合、エンドポイントは https://oss-cn-hangzhou.aliyuncs.com に設定します。
endpoint = "https://oss-cn-hangzhou.aliyuncs.com"
# エンドポイントに対応するリージョン ID を指定します。例: cn-hangzhou。署名アルゴリズム V4 を使用する場合は、このパラメーターが必要です。
region = "cn-hangzhou"
# バケット名を指定します。
bucket = oss2.Bucket(auth, endpoint, "yourBucketName", region=region)
# オブジェクトの完全なパスを指定します。完全なパスにはバケット名を含めないでください。例: exampledir/exampleobject.txt。
key = 'exampledir/exampleobject.txt'
# アップロード ID を指定します。アップロード ID は InitiateMultipartUpload 操作の応答から取得できます。
upload_id = 'yourUploadId'
# 指定されたアップロード ID のマルチパートアップロードタスクをキャンセルします。アップロード済みのフラグメントは削除されます。
bucket.abort_multipart_upload(key, upload_id)アップロード済みフラグメントの一覧表示
oss2.PartIterator を使用して、指定されたアップロード ID でアップロードされたすべてのフラグメントを一覧表示できます。各フラグメントには、フラグメント番号、ETag、サイズが含まれます。
# -*- coding: utf-8 -*-
import os
import oss2
from oss2.credentials import EnvironmentVariableCredentialsProvider
# 環境変数からアクセス認証情報を取得します。サンプルコードを実行する前に、OSS_ACCESS_KEY_ID および OSS_ACCESS_KEY_SECRET 環境変数が設定済みであることを確認してください。
auth = oss2.ProviderAuthV4(EnvironmentVariableCredentialsProvider())
# バケットが配置されているリージョンのエンドポイントを指定します。たとえば、バケットが中国 (杭州) リージョンにある場合、エンドポイントは https://oss-cn-hangzhou.aliyuncs.com に設定します。
endpoint = "https://oss-cn-hangzhou.aliyuncs.com"
# エンドポイントに対応するリージョン ID を指定します。例: cn-hangzhou。署名アルゴリズム V4 を使用する場合は、このパラメーターが必要です。
region = "cn-hangzhou"
# バケット名を指定します。
bucket = oss2.Bucket(auth, endpoint, "yourBucketName", region=region)
# オブジェクトの完全なパスを指定します。完全なパスにはバケット名を含めないでください。例: exampledir/exampleobject.txt。
key = 'exampledir/exampleobject.txt'
# アップロード ID を指定します。アップロード ID は InitiateMultipartUpload 操作の応答から取得できます。マルチパートアップロードタスクを CompleteMultipartUpload 操作で完了する前に、アップロード ID を取得しておく必要があります。
upload_id = 'yourUploadId'
# 指定されたアップロード ID を使用してアップロードされたフラグメントを一覧表示します。
for part_info in oss2.PartIterator(bucket, key, upload_id):
print('part_number:', part_info.part_number)
print('etag:', part_info.etag)
print('size:', part_info.size)マルチパートアップロードタスクの一覧表示
特定のオブジェクトに関するタスクの一覧表示
同じオブジェクトに対して init_multipart_upload() を呼び出すたびに、異なるアップロード ID が生成されます。oss2.ObjectUploadIterator を使用して、オブジェクトのアクティブなマルチパートアップロードタスクをすべて一覧表示できます。
# -*- coding: utf-8 -*-
import os
import oss2
from oss2.credentials import EnvironmentVariableCredentialsProvider
# 環境変数からアクセス認証情報を取得します。サンプルコードを実行する前に、OSS_ACCESS_KEY_ID および OSS_ACCESS_KEY_SECRET 環境変数が設定済みであることを確認してください。
auth = oss2.ProviderAuthV4(EnvironmentVariableCredentialsProvider())
# バケットが配置されているリージョンのエンドポイントを指定します。たとえば、バケットが中国 (杭州) リージョンにある場合、エンドポイントは https://oss-cn-hangzhou.aliyuncs.com に設定します。
endpoint = "https://oss-cn-hangzhou.aliyuncs.com"
# エンドポイントに対応するリージョン ID を指定します。例: cn-hangzhou。署名アルゴリズム V4 を使用する場合は、このパラメーターが必要です。
region = "cn-hangzhou"
# バケット名を指定します。
bucket = oss2.Bucket(auth, endpoint, "yourBucketName", region=region)
# オブジェクトの完全なパスを指定します。完全なパスにはバケット名を含めないでください。例: exampledir/exampleobject.txt。
key = 'exampledir/exampleobject.txt'
# オブジェクトのすべてのマルチパートアップロードタスクを一覧表示します。
for upload_info in oss2.ObjectUploadIterator(bucket, key):
print('key:', upload_info.key)
print('upload_id:', upload_info.upload_id)バケット内のすべてのタスクの一覧表示
oss2.MultipartUploadIterator を使用して、バケット内のアクティブなマルチパートアップロードタスクをすべて一覧表示できます。
# -*- coding: utf-8 -*-
import os
import oss2
from oss2.credentials import EnvironmentVariableCredentialsProvider
auth = oss2.ProviderAuthV4(EnvironmentVariableCredentialsProvider())
# バケットが配置されているリージョンのエンドポイントを指定します。たとえば、バケットが中国 (杭州) リージョンにある場合、エンドポイントは https://oss-cn-hangzhou.aliyuncs.com に設定します。
endpoint = "https://oss-cn-hangzhou.aliyuncs.com"
# エンドポイントに対応するリージョン ID を指定します。例: cn-hangzhou。署名アルゴリズム V4 を使用する場合は、このパラメーターが必要です。
region = "cn-hangzhou"
# バケット名を指定します。
bucket = oss2.Bucket(auth, endpoint, "yourBucketName", region=region)
# バケット内のすべてのマルチパートアップロードタスクを一覧表示します。
for upload_info in oss2.MultipartUploadIterator(bucket):
print('key:', upload_info.key)
print('upload_id:', upload_info.upload_id)オブジェクト名のプレフィックスによるタスクのフィルター
prefix パラメーターを渡すことで、指定されたプレフィックスで始まるオブジェクトのマルチパートアップロードタスクのみをフィルターできます。
# -*- coding: utf-8 -*-
import os
import oss2
from oss2.credentials import EnvironmentVariableCredentialsProvider
auth = oss2.ProviderAuthV4(EnvironmentVariableCredentialsProvider())
# バケットが配置されているリージョンのエンドポイントを指定します。たとえば、バケットが中国 (杭州) リージョンにある場合、エンドポイントは https://oss-cn-hangzhou.aliyuncs.com に設定します。
endpoint = "https://oss-cn-hangzhou.aliyuncs.com"
# エンドポイントに対応するリージョン ID を指定します。例: cn-hangzhou。署名アルゴリズム V4 を使用する場合は、このパラメーターが必要です。
region = "cn-hangzhou"
# バケット名を指定します。
bucket = oss2.Bucket(auth, endpoint, "yourBucketName", region=region)
# バケット内でオブジェクト名が test プレフィックスを含むマルチパートアップロードタスクを一覧表示します。
for upload_info in oss2.MultipartUploadIterator(bucket, prefix='test'):
print('key:', upload_info.key)
print('upload_id:', upload_info.upload_id)未完了のマルチパートアップロードのクリーンアップ
マルチパートアップロードが中断され、AbortMultipartUpload が呼び出されなかった場合、アップロード済みのフラグメントはバケット内に残り、ストレージコストが発生します。以下のいずれかの方法でこれらを削除してください。
参照
マルチパートアップロードには、以下の 3 つの API 操作が含まれます。
関連操作:
AbortMultipartUpload — マルチパートアップロードのキャンセル
ListParts — アップロード済みフラグメントの一覧表示
ListMultipartUploads — 進行中のマルチパートアップロードタスクの一覧表示