AWS S3, iki grup arasında dosya ve klasör kopyalama


112

Bir AWS S3 paketinin içeriğini, önce içeriği yerel dosya sistemine indirmeden ikinci bir AWS S3 klasörüne kopyalamama yardımcı olacak bir araç arıyordum.

AWS S3 konsol kopyalama seçeneğini kullanmayı denedim ancak bu, bazı iç içe geçmiş dosyaların eksik olmasına neden oldu.

Transmit uygulamasını kullanmayı denedim (Panic tarafından). Yinelenen komut, dosyaları önce yerel sisteme indirir, ardından onları ikinci gruba geri yükler, bu da oldukça verimsizdir.


Eşzamanlı istek sayınızı artırmayı düşünün aws configure set default.s3.max_concurrent_requests 200 Daha fazla ayrıntı ve seçenek için bu
gönderiye bakın

Yanıtlar:


176

S3 Buckets arasında kopyalama

AWS (kısa süre önce), paketler arasında kopyalamak için bir komut satırı arabirimi yayınladı.

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

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

Bu , bir hedef paketten diğerine kopyalayacaktır .

Belgelere buradan bakın: S3 CLI Belgeleri


EC2'den çalıştırdım ve yaklaşık 5 saniyede 80MB kopyalandı.
Stew-au

1
Tam olarak ihtiyacım olan şey, çünkü aws-sdk gem'in tüm paketi bir seferde kopyalamak veya senkronize etmek için bir özelliği yok. Teşekkürler!
odigity

Aşağıdaki hatayı atıyorA 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 Kullandığınız paket adı yanlış. Ya yanlış ön ek kullanıyorsunuz ya da kovaya atıfta bulunmanın eski yolunu kullanıyorsunuz. Paket adınızı tam olarak yönetici konsolunuzda kontrol edin.
Layke

8
Cli aracını ilk kez kullanıyorsanız, 'aws configure' komutunu çalıştırmanız ve kredilerinizi girmeniz gerektiğini unutmayın
S ..

41

Aws-sdk geminin kullanıldığı basitleştirilmiş bir örnek:

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

Kopyalama işlemini farklı paketler arasında gerçekleştirmek istiyorsanız, hedef paket adını belirtin:

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

41

Artık bunu S3 yönetici arayüzünden yapabilirsiniz. Tek bir gruba gidin ve tüm klasörlerinizi seçin actions->copy. Ardından yeni kovanıza gidin actions->paste.


4
Müthiş! Web arayüzüne atıfta bulunuyor. Diğerlerinin çoğunun aksine, bunu bir iPad'den yapabilirim.
Jacob Foshee

2
Bu rastgele olarak alt klasörlerdeki iç içe geçmiş nesneleri dışarıda bırakır - 3 yıl sonra ve AWS hala bu tür temel bir hatayı düzeltemez!
RunLoop

aynı bölgeler için mi yoksa hepsi için mi?
hakiko

1
Bu sorunlar Amazon tarafından herhangi bir yerde belgelendi mi? @RunLoop
davetapley

1
@dukedave Bilmiyorum ve bir süre sonra tekrar test etmedim, çünkü bu mükemmel çalıştı.
RunLoop

8

En son aws-sdk gem ile mümkündür , kod örneğine bakın:

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})

daha fazla ayrıntı: aws-s3 gem kullanarak kovalar arasında dosya kopyalama


Sunucular arasında nasıl kopyalama yapılacağını gösterdiğiniz için teşekkür ederiz. Bizden Singapur sunucusuna kopyalamaya çalışıyorum.
Arcolye

@Arcolye AWS Singapur'da gecikme şimdi nasıl? Bir yıl önce yavaş ve tutarsızdı.
Anatoly

7

Farklı bölgelerdeki kovalar arasında kopyalama

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

Yukarıdaki komut, Avrupa'daki (eu-west-1) bir kovadan Japonya'ya (ap-kuzeydoğu-1) bir dosya kopyalar. Bu komutla paketinizin bölgesi için kod adını alabilirsiniz:

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

Bu arada, S3 web konsolunda Kopyala ve Yapıştır'ı kullanmak kolaydır, ancak kaynak paketinden tarayıcıya indirilir ve ardından hedef pakete yüklenir. "Aws s3" kullanmak benim için çok daha hızlıydı.


6

Ben oluşturduk Docker yürütülebilir ait s3s3mirror aracı. Bir AWS S3 klasöründen diğerine kopyalama ve yansıtma için bir yardımcı program.

Paralel KOPYALAMAYA izin veren iş parçacıklı ve bellek açısından çok verimli, s3cmd'nin tamamen başarısız olduğu yerlerde başarılı olur.

Kullanımı:

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

Seçeneklerin tam listesi için şunu deneyin:

docker run pmoust/s3s3mirror 


5

Şimdiye kadar muhtemelen iyi bir çözüm bulduğunuzu tahmin ediyorum, ancak bu sorunla karşılaşan diğerleri için (yakın zamanda olduğum gibi), özellikle bir S3 kovasını diğerine yansıtma amacıyla basit bir yardımcı program hazırladım. eşzamanlı, ancak CPU ve bellek açısından verimli bir şekilde.

Burada bir Apache Lisansı altında github'da: https://github.com/cobbzilla/s3s3mirror

Çok büyük bir kovanız olduğunda ve maksimum performans arıyorsanız, denemeye değer olabilir.

Denemeye karar verirseniz, herhangi bir geri bildiriminiz varsa lütfen bize bildirin.


S3s3mirror ile harika bir deneyim yaşadım. Onu bir m1.small EC2 düğümünde kurabildim ve yaklaşık 2 saatte 1,5 milyon nesneyi kopyaladım. Kurulum, Maven ve Java'ya aşina olmamamdan dolayı biraz zordu, ancak her şeyi yüklemek için Ubuntu'da yalnızca birkaç apt-get komutu gerekiyordu. Son bir not: Eğer (benim gibi) büyük, önemli bir s3 paketinde bilinmeyen bir komut dosyası çalıştırma konusunda endişeleniyorsanız, kopyadan kopyalamada salt okunur erişimi olan özel bir kullanıcı oluşturun ve bu kimlik bilgilerini kullanın. Yanlışlıkla silinme şansı sıfır.
Micah

4

Kabuk içindeyseniz ve birden çok dosyayı kopyalamak istiyorsanız, ancak tüm dosyaları kopyalamıyorsanız: s3cmd cp - recursive s3: // BUCKET1 / OBJECT1 s3: // BUCKET2 [/ OBJECT2]


3

S3 paketini yedekleyen bir komut dosyası yazdım: 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()

Bunu bir komisyon görevinde kullanıyorum (bir Rails uygulaması için):

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 ile ilgileniyorsanız bunun için bir düğüm modülü olduğunu duydum: p

Gönderen Knox kopyalı docs:

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"

Bu javascript değil, üzgünüm ... (evet, kahve yazısının farkındayım ve yine de kullanabilirsiniz, javascript kullanamazsınız)
Victor Schröder

1

Bunu bir EMR kümesinde s3distcp kullanarak da yapabileceğiniz konusunda bilgilendirildim. Büyük dosyalar içeren veriler için daha hızlı olması gerekiyordu. Küçük veri setlerinde yeterince iyi çalışıyor - ancak çok az veri için kurması gereken öğrenme eğrisi göz önüne alındığında başka bir çözümü tercih ederdim (daha önce EMR ile hiç çalışmadım).

AWS Belgelerinden bir bağlantı: http://docs.aws.amazon.com/ElasticMapReduce/latest/DeveloperGuide/UsingEMR_s3distcp.html

Güncelleme: Aynı veri kümesi için s3s3mirror, s3distcp veya AWS cli'den çok daha hızlıydı. Kurulumu da çok daha kolay.


1

Yerel olarak indirmeden bir S3 klasöründen aynı veya başka bir S3 klasörüne kopyalamak oldukça basittir. Aşağıdaki kabuk komutunu kullanın.

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

Bu, tüm dosyaları kaynak paketin SourceFoldernameklasöründen hedef paketin klasörüne kopyalar TargetFoldername. Yukarıdaki kodda, lütfen değiştirin AccessKey, SecurityKeyve ExternalBucketsenin tekabül değerlerle.


Nedir hdfs?
Anthony Kong

1

AWS cli https://aws.amazon.com/cli/ adresinden yapabilirsiniz

aws s3 ls - Bu, tüm S3 kovalarını listeleyecektir

aws cp --recursive s3://<source bucket> s3://<destination bucket> - Bu, dosyaları bir paketten diğerine kopyalar

Not * Bölgeler arası çoğaltma paketleri oluştururken çok kullanışlıdır. Yukarıdakileri yaparak, tüm dosyalarınız izlenir ve kaynak bölge dosyasında yapılan bir güncelleme, çoğaltılan pakete yayılır. Dosya silme hariç her şey senkronize edilir.

CRR için, paketlerde sürüm oluşturmayı etkinleştirdiğinizden emin olun.


0

aws s3 syncCli komutuna ne dersiniz ? aws s3 sync s3: // paket1 / s3: // paket2 /


0

Neel Bhaat'ın bu blogda açıkladığı gibi , bu amaçla kullanılabilecek birçok farklı araç var. Bazıları AWS tarafından sağlanır ve çoğu üçüncü taraf araçlardır. Tüm bu araçlar, AWS hesap anahtarınızı ve sırrınızı aracın kendisine kaydetmenizi gerektirir. Üçüncü taraf araçlarını kullanırken çok dikkatli olun, çünkü kaydettiğiniz kimlik bilgileri size, tüm değerinize mal olabilir ve sizi öldürebilir.

Bu nedenle, bu amaçla her zaman AWS CLI kullanmanızı öneririm . Bunu bu bağlantıdan kolayca kurabilirsiniz . Ardından, aşağıdaki komutu çalıştırın ve anahtarınızı, gizli değerlerinizi AWS CLI'ye kaydedin.

aws configure

AWS S3 Bucket'inizi yerel makinenizle eşitlemek için aşağıdaki komutu kullanın. (Yerel makinede AWS CLI kurulu olmalıdır)

aws s3 sync <source> <destination>

Örnekler:

1) AWS S3'ten Yerel Depolamaya

aws s3 sync <S3Uri> <LocalPath>

2) Yerel Depolamadan AWS S3'e

aws s3 sync <LocalPath> <S3Uri>

3) AWS s3 kovasından başka bir kovaya

aws s3 sync <S3Uri> <S3Uri> 

0

S3 demetini kopyalamanın en iyi yolu AWS CLI kullanmaktır .

Bu 3 adımı içerir:

  1. Sunucunuza AWS CLI'yi kurma.
**https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-install.html**
  1. Paketleri iki AWS hesabı arasında kopyalıyorsanız, her pakete doğru politikayı eklemeniz gerekir.

  2. Bundan sonra, bir paketten diğerine kopyalamak için bu komutu kullanın.

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

Ayrıntıları adım 2 ve 3. adımda bu linkte verilmiştir:

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


Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.