AWS S3は2つのバケット間でファイルとフォルダーをコピーします


112

ローカルファイルシステムにコンテンツを最初にダウンロードすることなく、AWS S3バケットのコンテンツを2番目のAWS S3バケットにコピーするのに役立つツールを探していました。

AWS S3コンソールのコピーオプションを使用しようとしましたが、ネストされたファイルの一部が失われていました。

送信アプリ(パニックによる)を使用しようとしました。duplicateコマンドは、最初にファイルをローカルシステムにダウンロードし、次に2番目のバケットにアップロードします。これは非常に非効率的です。


あなたの同時リクエスト数を増やすことを検討しaws configure set default.s3.max_concurrent_requests 200 、より詳細とオプションについては、この記事を参照してくださいstackoverflow.com/questions/4663016/...
Balmipour

回答:


175

S3バケット間でコピー

AWS(最近)は、バケット間でコピーするためのコマンドラインインターフェースをリリースしました。

http://aws.amazon.com/cli/

$ aws s3 sync s3://mybucket-src s3://mybucket-target --exclude *.tmp
..

これにより、1つのターゲットバケットから別のバケットにコピーされます。

こちらのドキュメントをご覧ください。S3CLIドキュメント


EC2から実行すると、約5秒で80MBがコピーされます。
Stew-au

1
aws-sdk gemにはバケット全体を一度にコピーまたは同期する機能がないため、まさに私が必要としていたものです。ありがとう!
オディティー14

それは次のエラーをスローしますA client error (PermanentRedirect) occurred when calling the ListObjects operation: The bucket you are attempting to access must be addressed using the specified endpoint. Please send all future requests to this endpoint.
Giovanni Bitliner

@GiovanniBitliner使用しているバケット名が正しくありません。間違った接頭辞を使用しているか、バケットを参照する古い方法を使用しています。管理コンソールでバケット名を正確に確認してください。
Layke 2014年

8
注これは、あなたが「AWSのconfigure」を実行し、あなたのcredsをを入力する必要があり、CLIツール使用して、あなたの最初の時間である場合
.. Sを

41

aws-sdk gemを使用した簡単な例:

AWS.config(:access_key_id => '...', :secret_access_key => '...')
s3 = AWS::S3.new
s3.buckets['bucket-name'].objects['source-key'].copy_to('target-key')

異なるバケット間でコピーを実行する場合は、ターゲットバケット名を指定します。

s3.buckets['bucket-name'].objects['source-key'].copy_to('target-key', :bucket_name => 'target-bucket')

41

これで、S3管理インターフェイスから実行できます。1つのバケットに移動して、すべてのフォルダを選択しますactions->copy。次に、新しいバケットに移動しますactions->paste


4
驚くばかり!彼はWebインターフェースについて言及しています。他のほとんどとは異なり、私はこれをiPadから行うことができました。
Jacob Foshee、2014

2
これにより、サブフォルダー内のネストされたオブジェクトがランダムに除外されます-3年後、AWSはまだそのような基本的なバグを修正できません!
RunLoop 2016

同じ地域ですか、それともすべてですか。
hakiko 2017

1
これらの問題は、Amazonによって文書化されていますか?@RunLoop
davetapley

1
@dukedave完全に機能したため、コマンドラインからコピーを実行したため、わからないので、しばらくテストしていません。
RunLoop

8

最近のaws-sdk gemで可能です。コードサンプルをご覧ください。

require 'aws-sdk'

AWS.config(
  :access_key_id     => '***',
  :secret_access_key => '***',
  :max_retries       => 10
)

file     = 'test_file.rb'
bucket_0 = {:name => 'bucket_from', :endpoint => 's3-eu-west-1.amazonaws.com'}
bucket_1 = {:name => 'bucket_to',   :endpoint => 's3.amazonaws.com'}

s3_interface_from = AWS::S3.new(:s3_endpoint => bucket_0[:endpoint])
bucket_from       = s3_interface_from.buckets[bucket_0[:name]]
bucket_from.objects[file].write(open(file))

s3_interface_to   = AWS::S3.new(:s3_endpoint => bucket_1[:endpoint])
bucket_to         = s3_interface_to.buckets[bucket_1[:name]]
bucket_to.objects[file].copy_from(file, {:bucket => bucket_from})

詳細:aws-s3 gemを使用してバケット間でファイルをコピーする方法


サーバー間でコピーする方法を示していただきありがとうございます。私たちのサーバーからシンガポールのサーバーにコピーしようとしています。
Arcolye 2013年

@Arcolye AWSシンガポールでのレイテンシーはどうですか?1年前は遅く、一貫性がありませんでした。
アナトリー

7

異なるリージョンのバケット間でコピーする

$ aws s3 cp s3://src_bucket/file  s3://dst_bucket/file --source-region eu-west-1 --region ap-northeast-1

上記のコマンドは、ヨーロッパのバケット(eu-west-1)から日本(ap-northeast-1)にファイルをコピーします。次のコマンドを使用して、バケットのリージョンのコード名を取得できます。

$ aws s3api get-bucket-location --bucket my_bucket

ちなみに、S3ウェブコンソールでコピーと貼り付けを使用するのは簡単ですが、ソースバケットからブラウザにダウンロードしてから、宛先バケットにアップロードするようです。「aws s3」を使用した方がはるかに高速でした。


6

s3s3mirrorツールのDocker実行可能ファイルを作成しました。AWS S3バケットから別のバケットにコピーおよびミラーリングするユーティリティ。

スレッド化されており、並列COPYと非常にメモリ効率が高く、s3cmdが完全に失敗した場合に成功します。

使用法:

docker run -e AWS_ACCESS_KEY_ID=FOO -e AWS_SECRET_ACCESS_KEY=BAR pmoust/s3s3mirror [OPTIONS] source_bucket[/prefix] dest_bucket[/prefix]

オプションの完全なリストについては、以下を試してください。

docker run pmoust/s3s3mirror 


5

私はあなたがおそらく今までに良い解決策を見つけたと思いますが、この問題に遭遇している他の人のために(ちょうど最近だったように)、あるS3バケットを別のS3バケットにミラーリングする目的のために特に簡単なユーティリティを作成しました非常に並行性がありながら、CPUとメモリの効率的な方法。

これはApacheライセンスの下のgithubにあります:https : //github.com/cobbzilla/s3s3mirror

非常に大きなバケットがあり、最大のパフォーマンスを求めている場合は、試す価値があるかもしれません。

試してみることにした場合は、フィードバックがありましたらお知らせください。


私はs3s3mirrorで素晴らしい経験をしました。私はそれをm1.small EC2ノードにセットアップし、約2時間で150万個のオブジェクトをコピーすることができました。MavenとJavaに慣れていないため、セットアップは少し大変でしたが、Ubuntuでいくつかのapt-getコマンドを実行するだけで、すべてをインストールできました。最後に、(私のように)大きくて重要なs3バケットで不明なスクリプトを実行することが心配な場合は、copy-fromバケットへの読み取り専用アクセス権を持つ特別なユーザーを作成し、それらの認証情報を使用します。誤って削除する可能性はゼロです。
ミカ2013年

4

シェルですべてのファイルではなく複数のファイルをコピーする場合:s3cmd cp --recursive s3:// BUCKET1 / OBJECT1 s3:// BUCKET2 [/ OBJECT2]


3

S3バケットをバックアップするスクリプトを作成しました:https : //github.com/roseperrone/aws-backup-rake-task

#!/usr/bin/env python
from boto.s3.connection import S3Connection
import re
import datetime
import sys
import time

def main():
    s3_ID = sys.argv[1]
    s3_key = sys.argv[2]
    src_bucket_name = sys.argv[3]
    num_backup_buckets = sys.argv[4]
    connection = S3Connection(s3_ID, s3_key)
    delete_oldest_backup_buckets(connection, num_backup_buckets)
    backup(connection, src_bucket_name)

def delete_oldest_backup_buckets(connection, num_backup_buckets):
    """Deletes the oldest backup buckets such that only the newest NUM_BACKUP_BUCKETS - 1 buckets remain."""
    buckets = connection.get_all_buckets() # returns a list of bucket objects
    num_buckets = len(buckets)

    backup_bucket_names = []
    for bucket in buckets:
        if (re.search('backup-' + r'\d{4}-\d{2}-\d{2}' , bucket.name)):
            backup_bucket_names.append(bucket.name)

    backup_bucket_names.sort(key=lambda x: datetime.datetime.strptime(x[len('backup-'):17], '%Y-%m-%d').date())

    # The buckets are sorted latest to earliest, so we want to keep the last NUM_BACKUP_BUCKETS - 1
    delete = len(backup_bucket_names) - (int(num_backup_buckets) - 1)
    if delete <= 0:
        return

    for i in range(0, delete):
        print 'Deleting the backup bucket, ' + backup_bucket_names[i]
        connection.delete_bucket(backup_bucket_names[i])

def backup(connection, src_bucket_name):
    now = datetime.datetime.now()
    # the month and day must be zero-filled
    new_backup_bucket_name = 'backup-' + str('%02d' % now.year) + '-' + str('%02d' % now.month) + '-' + str(now.day);
    print "Creating new bucket " + new_backup_bucket_name
    new_backup_bucket = connection.create_bucket(new_backup_bucket_name)
    copy_bucket(src_bucket_name, new_backup_bucket_name, connection)


def copy_bucket(src_bucket_name, dst_bucket_name, connection, maximum_keys = 100):
    src_bucket = connection.get_bucket(src_bucket_name);
    dst_bucket = connection.get_bucket(dst_bucket_name);

    result_marker = ''
    while True:
        keys = src_bucket.get_all_keys(max_keys = maximum_keys, marker = result_marker)

        for k in keys:
            print 'Copying ' + k.key + ' from ' + src_bucket_name + ' to ' + dst_bucket_name

            t0 = time.clock()
            dst_bucket.copy_key(k.key, src_bucket_name, k.key)
            print time.clock() - t0, ' seconds'

        if len(keys) < maximum_keys:
            print 'Done backing up.'
            break

        result_marker = keys[maximum_keys - 1].key

if  __name__ =='__main__':main()

これをrakeタスクで使用します(Railsアプリの場合):

desc "Back up a file onto S3"
task :backup do
     S3ID = "AKIAJM3NRWC7STXWUWVQ"
     S3KEY = "0A5kuzV+E1dkaPjZxHQAezz1GlSddJd0iS5sNpry"
     SRCBUCKET = "primary-mzgd"
     NUM_BACKUP_BUCKETS = 2

     Dir.chdir("#{Rails.root}/lib/tasks")
     system "./do_backup.py #{S3ID} #{S3KEY} #{SRCBUCKET} #{NUM_BACKUP_BUCKETS}"
end

1

javascript:pを使用している場合は、そのためのノードモジュールがあると聞きます

ノックスコピードキュメント:

knoxCopy = require 'knox-copy'

client = knoxCopy.createClient
  key: '<api-key-here>'
  secret: '<secret-here>'
  bucket: 'backups'

client.copyBucket
  fromBucket: 'uploads'
  fromPrefix: '/nom-nom'
  toPrefix: "/upload_backups/#{new Date().toISOString()}"
  (err, count) ->
     console.log "Copied #{count} files"

これはjavascriptのではありません、申し訳ありません...(はい、私はCoffeeScriptのを知って、あなたがそれを使用することができますよ、まだ、ないジャバスクリプト)
ビクターシュレーダー

1

EMRクラスターでs3distcpを使用してこれを行うこともできると通知されました。大きなファイルを含むデータの方が速いと思われます。小さなデータセットで十分に機能しますが、非常に少ないデータを設定するために必要な学習曲線を考えると、別のソリューションを選択したほうがよいでしょう(これまでにEMRを使用したことがない)。

AWSドキュメントからのリンクは次のとおりです:http : //docs.aws.amazon.com/ElasticMapReduce/latest/DeveloperGuide/UsingEMR_s3distcp.html

更新:同じデータセットの場合、s3s3mirrorはs3distcpまたはAWS cliよりもはるかに高速でした。セットアップもはるかに簡単です。


1

ローカルにダウンロードせずに1つのS3バケットから同じまたは別のS3バケットにコピーするには、非常に簡単です。以下のシェルコマンドを使用します。

hdfs dfs -cp -f "s3://AccessKey:SecurityKey@ExternalBucket/SourceFoldername/*.*" "s3://AccessKey:SecurityKey@ExternalBucket/TargetFoldername"

これにより、すべてのファイルがソースバケットのSourceFoldernameフォルダーからターゲットバケットのTargetFoldernameフォルダーにコピーされます。上記のコードでAccessKeySecurityKeyExternalBucketを対応する値に置き換えてください。


なにhdfs
アンソニーコング

1

AWS cli https://aws.amazon.com/cli/からあなたが行うことができます

aws s3 ls -すべてのS3バケットが一覧表示されます

aws cp --recursive s3://<source bucket> s3://<destination bucket> -これにより、ファイルがバケット間でコピーされます

注*クロスリージョンレプリケーションバケットを作成する場合に非常に役立ちます。上記を実行すると、ファイルがすべて追跡され、ソースリージョンファイルへの更新がレプリケートされたバケットに反映されます。ファイルの削除以外はすべて同期されます。

CRRの場合は、バケットでバージョニングが有効になっていることを確認してください。


0

aws s3 synccliコマンドはどうでしょう。aws s3 sync s3:// bucket1 / s3:// bucket2 /


0

Neel Bhaatがこのブログで説明したようにで、この目的に使用できるさまざまなツールがあります。AWSが提供するものもあり、ほとんどがサードパーティのツールです。これらすべてのツールでは、AWSアカウントキーとシークレットをツール自体に保存する必要があります。サードパーティのツールを使用するときは、十分な注意を払ってください。保存した資格情報によって、価値がなくなり、価値がなくなり、死んでしまいます。

したがって、私は常にこの目的でAWS CLIを使用することをお勧めします。これはこのリンクから簡単にインストールできます。次に、次のコマンドを実行して、キー、シークレット値をAWS CLIに保存します。

aws configure

次のコマンドを使用して、AWS S3バケットをローカルマシンに同期します。(ローカルマシンにはAWS CLIがインストールされている必要があります)

aws s3 sync <source> <destination>

例:

1)AWS S3からローカルストレージへ

aws s3 sync <S3Uri> <LocalPath>

2)ローカルストレージからAWS S3へ

aws s3 sync <LocalPath> <S3Uri>

3)AWS s3バケットから別のバケットへ

aws s3 sync <S3Uri> <S3Uri> 

0

S3バケットをコピーする最良の方法は、AWS CLIを使用することです。

次の3つのステップが含まれます。

  1. サーバーにAWS CLIをインストールする。
**https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-install.html**
  1. 2つのAWSアカウント間でバケットをコピーする場合は、各バケットに正しいポリシーをアタッチする必要があります。

  2. この後、このコマンドを使用して、あるバケットから別のバケットにコピーします。

aws s3 sync s3://sourcebucket s3://destinationbucket

ステップ2ステップ3の詳細は、このリンクに記載されています。

https://aws.amazon.com/premiumsupport/knowledge-center/account-transfer-s3/


弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.