AWS S3 copia file e cartelle tra due bucket


112

Ero alla ricerca di uno strumento che mi aiutasse a copiare il contenuto di un bucket AWS S3 in un secondo bucket AWS S3 senza scaricare prima il contenuto nel file system locale.

Ho provato a utilizzare l'opzione di copia della console AWS S3 ma ciò ha comportato la mancanza di alcuni file nidificati.

Ho provato a utilizzare l'app Transmit (di Panic). Il comando duplicate scarica prima i file sul sistema locale, quindi li carica nuovamente nel secondo bucket, il che è abbastanza inefficiente.


Considerare di aumentare il valore del tuo richiesta concorrente aws configure set default.s3.max_concurrent_requests 200 Vedere questo post per maggiori dettagli e opzioni stackoverflow.com/questions/4663016/...
Balmipour

Risposte:


175

Copia tra bucket S3

AWS (solo di recente) ha rilasciato un'interfaccia a riga di comando per la copia tra i bucket.

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

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

Questo copierà da un bucket di destinazione a un altro bucket.

Vedere la documentazione qui: S3 CLI Documentation


L'ho eseguito da EC2 e ho copiato 80 MB in circa 5 secondi.
Stew-au

1
Esattamente quello di cui avevo bisogno, dal momento che aws-sdk gem non ha alcuna funzione per copiare o sincronizzare un intero bucket contemporaneamente. Grazie!
odigity

Lancia il seguente erroreA 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 Il nome del bucket che stai utilizzando non è corretto. Stai usando il prefisso sbagliato o stai usando il vecchio modo di fare riferimento al bucket. Controlla esattamente il nome del bucket nella console di amministrazione.
Layke

8
Nota se è la prima volta che utilizzi lo strumento cli, devi eseguire "aws configure" e inserire le tue credenziali
S ..

41

Un esempio semplificato usando la gemma aws-sdk:

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

Se desideri eseguire la copia tra diversi bucket, specifica il nome del bucket di destinazione:

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

41

Ora puoi farlo dall'interfaccia di amministrazione di S3. Basta andare in un bucket e selezionare tutte le tue cartelle actions->copy. Quindi spostati nel tuo nuovo secchio actions->paste.


4
Eccezionale! Si riferisce all'interfaccia web. A differenza della maggior parte degli altri, potrei farlo da un iPad.
Jacob Foshee

2
Ciò esclude casualmente gli oggetti nidificati nelle sottocartelle: 3 anni dopo, AWS non è ancora in grado di correggere un bug così semplice!
RunLoop

è per le stesse regioni o per tutte?
hakiko

1
Questi problemi sono documentati ovunque da Amazon? @RunLoop
davetapley

1
@dukedave Non lo so e non ho provato di nuovo da un po 'di tempo poiché ho fatto ricorso alla copia tramite la riga di comando poiché funzionava perfettamente.
RunLoop

8

È possibile con la recente gemma aws-sdk , vedere l'esempio di codice:

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

ulteriori dettagli: Come copiare file su bucket utilizzando aws-s3 gem


Grazie per aver mostrato come copiare sui server. Sto cercando di copiare da noi server a singapore server.
Arcolye

@Arcolye com'è ora la latenza in AWS Singapore? È stato lento e incoerente un anno fa.
Anatoly

7

Copia tra bucket in regioni diverse

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

Il comando precedente copia un file da un bucket in Europa (eu-west-1) in Giappone (ap-nordest-1). Puoi ottenere il nome in codice per la regione del tuo bucket con questo comando:

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

A proposito, l'utilizzo di Copia e Incolla nella console Web di S3 è facile, ma sembra che venga scaricato dal bucket di origine nel browser e quindi caricato nel bucket di destinazione. L'utilizzo di "aws s3" è stato molto più veloce per me.


6

Ho creato un eseguibile Docker dello strumento s3s3mirror . Un'utilità per la copia e il mirroring da un bucket AWS S3 a un altro.

È filettato consentendo COPIA parallela ed è molto efficiente in termini di memoria, riesce dove s3cmd fallisce completamente.

Uso:

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

Per un elenco completo delle opzioni prova:

docker run pmoust/s3s3mirror 


5

Immagino che tu abbia probabilmente trovato una buona soluzione ormai, ma per gli altri che stanno riscontrando questo problema (come lo ero solo di recente), ho creato una semplice utility appositamente allo scopo di eseguire il mirroring di un bucket S3 in un altro in un modo altamente concorrente, ma efficiente in termini di CPU e memoria.

È su GitHub con una licenza Apache qui: https://github.com/cobbzilla/s3s3mirror

Quando hai un secchio molto grande e stai cercando le massime prestazioni, potrebbe valere la pena provare.

Se decidi di provarlo, fammi sapere se hai dei commenti.


Ho avuto un'ottima esperienza con s3s3mirror. Sono stato in grado di configurarlo su un nodo EC2 m1.small e copiare 1,5 milioni di oggetti in circa 2 ore. L'installazione è stata un po 'difficile, a causa della mia scarsa familiarità con Maven e Java, ma sono bastati pochi comandi apt-get su Ubuntu per installare tutto. Un'ultima nota: se (come me) sei preoccupato di eseguire uno script sconosciuto su un bucket s3 grande e importante, crea un utente speciale con accesso di sola lettura sul bucket copy-from e usa quelle credenziali. Zero possibilità di cancellazione accidentale.
Michea

4

Se sei nella shell e desideri copiare più file ma non tutti i file: s3cmd cp --recursive s3: // BUCKET1 / OBJECT1 s3: // BUCKET2 [/ OBJECT2]


3

Ho scritto uno script che esegue il backup di un bucket 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()

Lo uso in un'attività di rake (per un'app 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

Ho sentito che c'è un modulo nodo per questo se ti piace javascript: p

Dai documenti di knox-copy :

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"

Questo non è javascript, mi dispiace ... (sì, sono a conoscenza di coffeescript e che puoi usarlo, ancora, non javascript)
Victor Schröder

1

Sono stato informato che puoi farlo anche usando s3distcp su un cluster EMR. Dovrebbe essere più veloce per i dati contenenti file di grandi dimensioni. Funziona abbastanza bene su piccoli set di dati, ma avrei preferito un'altra soluzione data la curva di apprendimento necessaria per impostare così pochi dati (non ho mai lavorato con EMR prima).

Ecco un collegamento dalla documentazione AWS: http://docs.aws.amazon.com/ElasticMapReduce/latest/DeveloperGuide/UsingEMR_s3distcp.html

Aggiornamento: per lo stesso set di dati, s3s3mirror era molto più veloce di s3distcp o del cli di AWS. Anche molto più facile da configurare.


1

Copiare da un bucket S3 allo stesso o un altro bucket S3 senza scaricare in locale, è piuttosto semplice. Usa il seguente comando di shell.

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

Questo copierà tutti i file dalla SourceFoldernamecartella del bucket di origine alla cartella del bucket di destinazione TargetFoldername. Nel codice di cui sopra, si prega di sostituire AccessKey, SecurityKeye ExternalBucketcon i propri valori corrispondenti.


Che cos'è hdfs?
Anthony Kong,

1

da AWS cli https://aws.amazon.com/cli/ potresti farlo

aws s3 ls - Questo elencherà tutti i bucket S3

aws cp --recursive s3://<source bucket> s3://<destination bucket> - Questo copierà i file da un bucket all'altro

Nota * Molto utile quando si creano bucket di replica su più regioni, facendo quanto sopra, tutti i file vengono tracciati e un aggiornamento al file della regione di origine verrà propagato al bucket replicato. Tutto tranne le eliminazioni dei file viene sincronizzato.

Per CRR assicurati di avere il controllo delle versioni abilitato sui bucket.


0

Che ne dici del aws s3 synccomando cli. aws s3 sync s3: // bucket1 / s3: // bucket2 /


0

Come ha spiegato Neel Bhaat in questo blog , ci sono molti strumenti diversi che possono essere usati per questo scopo. Alcuni sono forniti da AWS, mentre la maggior parte sono strumenti di terze parti. Tutti questi strumenti richiedono di salvare la chiave e il segreto dell'account AWS nello strumento stesso. Sii molto cauto quando usi strumenti di terze parti, poiché le credenziali in cui salvi potrebbero costarti, tutto il tuo valore e farti cadere morto.

Pertanto, consiglio sempre di utilizzare AWS CLI per questo scopo. Puoi semplicemente installarlo da questo link . Successivamente, esegui il comando seguente e salva la chiave e i valori segreti in AWS CLI.

aws configure

E utilizza il comando seguente per sincronizzare il tuo AWS S3 Bucket con la tua macchina locale. (La macchina locale dovrebbe avere AWS CLI installata)

aws s3 sync <source> <destination>

Esempi:

1) Per AWS S3 su archiviazione locale

aws s3 sync <S3Uri> <LocalPath>

2) Dallo storage locale ad AWS S3

aws s3 sync <LocalPath> <S3Uri>

3) Dal bucket AWS s3 a un altro bucket

aws s3 sync <S3Uri> <S3Uri> 

0

Il modo migliore per copiare il bucket S3 è utilizzare AWS CLI .

Comprende questi 3 passaggi:

  1. Installazione di AWS CLI sul tuo server.
**https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-install.html**
  1. Se stai copiando bucket tra due account AWS, devi allegare la policy corretta a ciascun bucket.

  2. Dopodiché usa questo comando per copiare da un bucket all'altro.

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

I dettagli del passaggio 2 e del passaggio 3 sono forniti in questo collegamento:

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


Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.