web-dev-qa-db-ja.com

Amazon S3で5GBを超えるファイルをコピーするにはどうすればよいですか?

Amazon S3 REST APIドキュメントには、PUT操作でのアップロードには5GBのサイズ制限があると記載されています。それよりも大きいファイルは、マルチパートを使用してアップロードする必要があります。

ただし、本質的に必要なのは、それよりも大きい可能性のあるファイルの名前を変更することです。名前の変更や移動の操作がないことを知っている限り、ファイルを新しい場所にコピーして、古い場所を削除する必要があります。 5GBを超えるファイルでそれはどの程度正確に行われますか?バケットからそれ自体にマルチパートアップロードを行う必要がありますか?その場合、ファイルを部分的に分割することはどのように機能しますか?

Botoのソースを読むと、5 GBを超えるファイルに対しては、このようなことは自動的には行われないようです。私が見逃した組み込みのサポートはありますか?

23
Pedro Werneck

名前の変更や移動の操作がないことがわかっている限り、ファイルを新しい場所にコピーして、古い場所を削除する必要があります。

正解です。5GB未満のオブジェクト/ファイルに対しては、 PUT Object --Copy 操作、続いて DELETE Object 操作(どちらも)を使用すると、非常に簡単に実行できます。 boto でサポートされています。もちろん copy_key() および delete_key() )を参照してください。

このPUT操作の実装により、AmazonS3にすでに保存されているオブジェクトのコピーが作成されます。 PUTコピー操作は、GETを実行してからPUTを実行するのと同じです。リクエストヘッダーx-amz-copy-sourceを追加すると、PUT操作でソースオブジェクトが宛先バケットにコピーされます。

ただし、5 GBを超えるオブジェクト/ファイルの場合、これは実際には不可能です。


[...]このAPIを使用して、1回のアトミック操作で最大5GBのサイズのオブジェクトのコピーを作成します。 ただし、5 GBを超えるオブジェクトをコピーするには、マルチパートアップロードAPIを使用する必要があります。概念情報[...]については、 マルチパートアップロードを使用したオブジェクトのアップロード [...][emphasis mine]にアクセスしてください。

一方、Botoは、 copy_part_from_key() メソッドを使用してこれもサポートしています。残念ながら、必要なアプローチはそれぞれの外部で文書化されていません プルリクエスト#425(マルチパートコピーコマンドを許可) (私はまだこれを試していません):

import boto
s3 = boto.connect_s3('access', 'secret')
b = s3.get_bucket('destination_bucket')
mp = b.initiate_multipart_upload('tmp/large-copy-test.mp4')
mp.copy_part_from_key('source_bucket', 'path/to/source/key', 1, 0, 999999999)
mp.copy_part_from_key('source_bucket', 'path/to/source/key', 2, 1000000000, 1999999999)
mp.copy_part_from_key('source_bucket', 'path/to/source/key', 3, 2000000000, 2999999999)
mp.copy_part_from_key('source_bucket', 'path/to/source/key', 4, 3000000000, 3999999999)
mp.copy_part_from_key('source_bucket', 'path/to/source/key', 5, 4000000000, 4999999999)
mp.copy_part_from_key('source_bucket', 'path/to/source/key', 6, 5000000000, 5500345712)
mp.complete_upload()

Javaまたは.NETで最終的にこれを実現する方法について、それぞれのサンプルを調査することをお勧めします。これにより、一般的なアプローチについてより多くの洞察が得られる可能性があります。 マルチパートアップロードを使用したオブジェクトのコピー)を参照してください。 API

幸運を!


付録

一般に、見過ごされがちなコピーに関する次の特性に注意してください。

オブジェクトをコピーするときは、ほとんどのメタデータ(デフォルト)を保持するか、新しいメタデータを指定できます。 ただし、ACLは保持されず、リクエストを行うユーザーに対してプライベートに設定されます。デフォルトのACL設定を上書きするには、x-amz-aclヘッダーを使用して、コピー要求を生成するときに新しいACLを指定します。詳細については、Amazon S3ACLを参照してください。 [重点鉱山]

23
Steffen Opel

上記は動作に非常に近いものでしたが、残念ながら、タイプミスmp.complete_upload()ではなくupload_complete()で終了する必要がありました。

AWS Javaの例に基づいて、5 GiBを超えるファイルでテストした、動作するbotos3マルチパートコピースクリプトをここに追加しました。

https://Gist.github.com/joshuadfranklin/5130355

10
joshuadfranklin

5ギガより大きいファイルをアップロードするこの方法を見つけ、Botoコピー手順で機能するように変更しました。これがオリジナルです: http://boto.cloudhackers.com/en/latest/s3_tut.html

import math
from boto.s3.connection import S3Connection
from boto.exception import S3ResponseError


conn = S3Connection(Host=[your_Host], aws_access_key_id=[your_access_key],
                    aws_secret_access_key=[your_secret_access_key])

from_bucket = conn.get_bucket('your_from_bucket_name')
key = from_bucket.lookup('my_key_name')
dest_bucket = conn.get_bucket('your_to_bucket_name')

total_bytes = key.size
bytes_per_chunk = 500000000

chunks_count = int(math.ceil(total_bytes/float(bytes_per_chunk)))
file_upload = dest_bucket.initiate_multipart_upload(key.name)
for i in range(chunks_count):
    offset = i * bytes_per_chunk
    remaining_bytes = total_bytes - offset
    print(str(remaining_bytes))
    next_byte_chunk = min([bytes_per_chunk, remaining_bytes])
    part_number = i + 1
    file_upload.copy_part_from_key(dest_bucket.name, key.name, part_number,
                                   offset, offset + next_byte_chunk - 1)
file_upload.complete_upload()
2
Matt Farguson