2017-01-19 1 views
0

boto3 apiを使用して2つの異なるアカウント間でバケットからキーをコピーしたいとします。 はboto3では、私は次のコードを実行され、コピーは基本的に私はGETからデータをフェッチし、別のアカウントに入れてそれを貼り付けています2つの異なる口座/接続間のboto3またはboto apiからのバケット/キーのパラレルコピー

source = boto3.client('s3') 
destination = boto3.client('s3') 
destination.put_object(source.get_object(Bucket='bucket', Key='key')) 

を働きました。 boto APIの類似ライン上

、Iは、上記のコードは、任意のタイプのデータをコピーする目的を達成以下

source = S3Connection() 
source_bucket = source.get_bucket('bucket') 
source_key = Key(source_bucket, key_name) 

destination = S3Connection() 
destination_bucket = destination.get_bucket('bucket') 
dist_key = Key(destination_bucket, source_key.key) 
dist_key.set_contents_from_string(source_key.get_contents_as_string()) 

を行っています。 しかし、速度は本当に非常に遅いです。 1GBのデータをコピーするのに15-20秒ほどかかる。私は100GBプラスをコピーしなければなりません。 私は各スレッドがコピー操作を行うpythonのmutithreadingを試みました。 1GBのコピーに30秒かかったため、パフォーマンスが悪かった。私はGILがここで問題になるかもしれないと思う。 私はマルチプロセッシングを行いました.1GBファイルの場合、15-20秒の単一プロセスと同じ結果が得られました。

48コアと128GB RAMを備えた非常にハイエンドなサーバーを使用しています。私の環境でのネットワーク速度は10GBPSです。 検索結果のほとんどは、同じアカウントのバケット間でデータをコピーし、アカウント間でデータをコピーしないことを示します。誰も私をここで案内することができますか?私のアプローチは間違っていますか?誰かがより良い解決策を持っていますか?

答えて

1

あなたはboto3のTransferManagerをチェックアウトする必要があります。マルチパートアップロードのスレッド化を自動的に効率的に処理します。詳細については、the docsを参照してください。

基本的には、upload_fileメソッドを使用する必要があり、TransferManagerは残りの処理を行います。

import boto3 

# Get the service client 
s3 = boto3.client('s3') 

# Upload tmp.txt to bucket-name at key-name 
s3.upload_file("tmp.txt", "bucket-name", "key-name") 
+0

提案をいただきありがとうございます。私は、アカウント間でデータを転送するためにboto3.upload_fileobj()を使用しました。 1GBファイルのコピーには17秒かかりました。 複数のプロセスでコードをまとめると、各プロセスのboto3.s3.transfer.TransferConfigでスレッド数が25に増えました。 1GBは9-10秒でコピーされました。 :) 私はTransferConfigパラメータで遊んでいます。うまくいけば1GBは5〜7秒でコピーされます。 乾杯 – bechkam7

2

はい、間違ったアプローチです。

はファイルをダウンロードしないでください。 AWSインフラストラクチャを使用しているため、効率的なAWSバックエンドコールを使用して作業を行う必要があります。あなたのアプローチはリソースを無駄にしています。

boto3.client.copyはこれよりもうまくいくでしょう。

さらに、達成しようとしていることを説明していません(例:これは何らかの複製要件ですか?)。

あなた自身の必要性を適切に理解すれば、サーバーを使わなくてもS3バケットイベントトリガー、ラムダなどはすべてサーバーなしでコピージョブを実行できます。二つの異なるAWSアカウントの間でファイルをコピーするには

、あなたがこのリンクをチェックアウトすることができますCopy S3 object between AWS account

注:

S3は、バケット名は一意でなければならない理由です、皆のための巨大な仮想オブジェクトストアです。これはまた、S3 "コントローラ"がファイルサーバに似た、多くの工夫をすることができることを意味します。レプリケーション、コピー、バックエンドのファイルを移動することができます。

宛先バケットに対する適切なIAMアクセス許可/ポリシーを設定する限り、オブジェクトは追加のサーバーなしでバケット間を移動できます。

これはファイルサーバーとほぼ同じです。ユーザーは「ダウンロード/アップロード」せずにファイルを互いにコピーすることができます。代わりに、すべてのユーザーに対して書き込み権限を持つフォルダを作成するだけで、すべてのファイルコピーがファイルサーバー内で実行されます。 強力なインスタンスや高性能ネットワークは、バックエンドS3コピーAPIを使用する必要はありません。

あなたの方法は、不要なネットワークトラフィックを作成する、同じファイルサーバーを使用しているユーザーからのFTPダウンロードファイルの試行と似ています。

+0

S3でファイルをコピーすることに問題がある場合は、これが正しい答えです。私はあなたの問題を誤解し、あなたはS3への転送/ S3からの転送でより多くのスループットを得る方法を探していると思っていました。そのために、TransferManagerを試してみてください。 – garnaat

+0

S3プロトコルのみでシステム間でデータをコピーしたい。 私はboto3.upload_fileobj()メソッドを使用しているより良い解決策を発見しました。 – bechkam7

+0

@ bechkam7:この「ネットワークダウンロード/アップロード」データ転送を続けると、パフォーマンスには役立ちません。同じS3領域内で、異なるバケット所有者であっても、適切なIAMロールと宛先バケットのアクセス許可を設定する限り、ネットワークトラフィックなしでバケット間でデータをコピー/移動できます。 – mootmoot

関連する問題