Il modo migliore per spostare i file tra i bucket S3?


89

Vorrei copiare quotidianamente alcuni file da un bucket di produzione a un bucket di sviluppo.

Ad esempio: copia productionbucket / feed / feedname / date in developmentbucket / feed / feedname / date

Poiché i file che desidero sono così profondi nella struttura delle cartelle, è troppo dispendioso in termini di tempo per andare in ciascuna cartella e copiare / incollare.

Ho giocato con il montaggio di unità su ciascun bucket e la scrittura di uno script batch di Windows, ma è molto lento e scarica inutilmente tutti i file / cartelle sul server locale ed esegue nuovamente il backup.

Risposte:


109

Aggiornare

Come sottolineato da alberge (+1), oggigiorno l'eccellente AWS Command Line Interface fornisce l'approccio più versatile per interagire con (quasi) tutte le cose AWS - nel frattempo copre la maggior parte delle API dei servizi e presenta anche comandi S3 di livello superiore per gestire il tuo caso d'uso in particolare, consulta il riferimento AWS CLI per S3 :

  • sync - Sincronizza directory e prefissi S3. Il vostro caso d'uso è coperto da Esempio 2 (più grana fine utilizzo con --exclude, --includee la gestione del prefisso ecc è anche disponibile):

    Il seguente comando di sincronizzazione sincronizza gli oggetti con un prefisso e un bucket specificato con gli oggetti con un altro prefisso e bucket specificato, copiando gli oggetti s3. [...]

    aws s3 sync s3://from_my_bucket s3://to_my_other_bucket
    

Per completezza, menzionerò che i comandi S3 di livello inferiore sono ancora disponibili anche tramite il comando secondario s3api , che consentirebbe di tradurre direttamente qualsiasi soluzione basata su SDK nell'AWS CLI prima di adottare eventualmente la sua funzionalità di livello superiore.


Risposta iniziale

Lo spostamento di file tra i bucket S3 può essere ottenuto mediante PUT Object - Copy API (seguito da DELETE Object ):

Questa implementazione dell'operazione PUT crea una copia di un oggetto già archiviato in Amazon S3. Un'operazione di copia PUT equivale a eseguire un GET e quindi un PUT. L'aggiunta dell'intestazione della richiesta, x-amz-copy-source, fa sì che l'operazione PUT copi l'oggetto di origine nel bucket di destinazione. fonte

Sono disponibili rispettivi esempi per tutti gli SDK AWS esistenti, consulta Copia di oggetti in un'unica operazione . Naturalmente, una soluzione basata su script sarebbe la prima scelta ovvia qui, quindi copiare un oggetto utilizzando l'SDK AWS per Ruby potrebbe essere un buon punto di partenza; se preferisci invece Python, lo stesso può essere ottenuto anche tramite boto , ovviamente, vedi il metodo copy_key()nella documentazione dell'API S3 di boto .

PUT Objectcopia solo i file, quindi dovrai eliminare esplicitamente un file tramite DELETE Objectancora dopo un'operazione di copia riuscita, ma saranno solo poche righe una volta che lo script generale che gestisce il bucket e i nomi dei file è a posto (ci sono anche i rispettivi esempi , vedere ad esempio Eliminazione di un oggetto per richiesta ).


Ho finito per scrivere lo script dell'operazione con l'SDK AWS in .NET
Matt Dell

1
@ MattDell puoi aggiungere la risposta .NET a questa domanda?
balexandre

1
Ciò che fa schifo è che Amazon non è molto chiaro se il comando di copia ha avuto successo o meno, quindi l'eliminazione dopo l'operazione sembra pericolosa.
James McMahon

Giusto per essere chiari, mi riferivo specificamente all'API Java. Ho aperto una domanda separata stackoverflow.com/questions/17581582
James McMahon,

Abbiamo ancora bisogno di un modo semplice per creare un unico ID e chiave in grado di leggere da un bucket e scrivere sull'altro. Soprattutto se i bucket sono tra account.
CMCDragonkai

65

La nuova AWS CLI ufficiale supporta nativamente la maggior parte delle funzionalità di s3cmd. In precedenza utilizzavo s3cmdo l'SDK AWS ruby ​​per eseguire operazioni del genere, ma la CLI ufficiale funziona alla grande per questo.

http://docs.aws.amazon.com/cli/latest/reference/s3/sync.html

aws s3 sync s3://oldbucket s3://newbucket

4
Questo dovrebbe essere votato in cima alla lista. È il modo corretto per sincronizzare i bucket e il più aggiornato in tutte queste risposte.
dft

Se hai problemi con gli errori 403 di accesso negato, consulta questo post del blog. Ha aiutato. alfielapeter.com/posts/…
crlane

3
copia interregionaleaws s3 sync s3://my-bucket-in-eu-west1 s3://my-bucket-in-eu-central1 --source-region=eu-west-1 --region=eu-central-1
equivalente8

se hai bisogno di eseguire questa notte di servizio sul server usa nohup aws s3 sync s3://my-bucket-in-eu-west1 s3://my-bucket-in-eu-central1 --source-region=eu-west-1 --region=eu-central-1 & thegeekstuff.com/2010/12/5-ways-to-execute-linux-command
equivalente 8

@alberge Esiste un modo per fornire la chiave di accesso e il segreto utilizzando l'argomento della riga di comando?
EmptyData

28

Per spostare / copiare da un bucket all'altro o allo stesso bucket, utilizzo lo strumento s3cmd e funziona bene. Per esempio:

s3cmd cp --recursive s3://bucket1/directory1 s3://bucket2/directory1
s3cmd mv --recursive s3://bucket1/directory1 s3://bucket2/directory1

28

Ho passato giorni interi a scrivere il mio strumento personalizzato per parallelizzare le copie richieste per questo, ma poi mi sono imbattuto nella documentazione su come ottenere il comando di sincronizzazione della CLI di AWS S3 per sincronizzare i bucket con una parallelizzazione massiccia . I seguenti comandi indicheranno all'AWS CLI di utilizzare 1.000 thread per eseguire i lavori (ciascuno un piccolo file o una parte di una copia in più parti) e guardare avanti 100.000 lavori:

aws configure set default.s3.max_concurrent_requests 1000
aws configure set default.s3.max_queue_size 100000

Dopo averli eseguiti, puoi utilizzare il semplice comando di sincronizzazione come segue:

aws s3 sync s3://source-bucket/source-path s3://destination-bucket/destination-path

Su una macchina m4.xlarge (in AWS - 4 core, 16 GB di RAM), per il mio caso (file 3-50 GB) la velocità di sincronizzazione / copia è passata da circa 9,5MiB / sa 700 + MiB / s, un aumento della velocità di 70 volte rispetto alla configurazione predefinita.

Aggiornamento: nota che S3CMD è stato aggiornato nel corso degli anni e queste modifiche ora sono effettive solo quando lavori con molti file di piccole dimensioni. Si noti inoltre che S3CMD su Windows (solo su Windows) è seriamente limitato nel throughput complessivo e può raggiungere solo 3 Gbps per processo, indipendentemente dalle dimensioni dell'istanza o dalle impostazioni utilizzate. Altri sistemi come S5CMD hanno lo stesso problema. Ne ho parlato con il team S3 e stanno esaminando la questione.


Grazie, sono riuscito a ottenere oltre 900 + MiB / s con la tua configurazione, enorme velocità rispetto a quella predefinita.
kozyr

@ James: l'API ci limita a raggiungere tali trasferimenti ad alta velocità? Sto utilizzando l'API transfermanager fornito da AWS Java SDK vs CLI da una macchina T2 EC2 per trasferire file da 2 GB. La differenza di tempo è ~ 5,5 volte (CLI - 14 secondi) rispetto a (SDK - 80 secondi). Inoltre, non vedo alcuna opzione per s3.max_queue_size in SDK. Eventuali commenti?
Dwarrior

@Dwarrior, entrambe queste impostazioni sono per la CLI. Quando si utilizza un SDK, è necessario gestire da soli tutte le richieste in coda. AWS support afferma di aver raggiunto circa l'80% del throughput massimo possibile tra EC2 e S3 utilizzando Linux (ovvero il throughput di rete dell'istanza EC2 pubblicizzato). Windows è un cittadino di seconda classe su AWS e non può ottenerne nemmeno la metà con gli strumenti forniti da Amazon e sembra che non abbiano intenzione di risolverlo. :-( Con una macchina T2, AWS non specifica esattamente quanta larghezza di banda si ottiene, anche se le cose migliorano leggermente se si configura un endpoint VPC S3.
James

@ James sono arrivato al punto di parallelizzare il mio elenco di file su cluster in Spark, combinandolo con la parallelizzazione all'interno di ogni partizione e quindi utilizzando transfermanager per i caricamenti paralleli per qualsiasi file dato. Vedo un miglioramento da 80 a 45 secondi dopo averlo fatto, ma manca ancora nel modo in cui la CLI gestisce da EC2. Grazie, però per questa configurazione. Ha anche migliorato drasticamente le prestazioni su Windows. In SDK, possiamo impostare il numero massimo di connessioni ma non la dimensione della coda, quindi penso che potremmo doverlo lasciare. :) Qualsiasi suggerimento su come gestire l'accodamento, qualsiasi codice di esempio che posso utilizzare come linea di base.
Dwarrior

2
S5Cmd ( github.com/peakgames/s5cmd ) è l'utilità che le persone del supporto AWS hanno utilizzato per il massimo rendimento. La dimensione dell'istanza fa una grande differenza. La nuova serie c5n è molto conveniente per il networking e arriva fino a un incredibile 100 Gbps.
James

13

Esempio .NET come richiesto:

using (client)
{
    var existingObject = client.ListObjects(requestForExisingFile).S3Objects; 
    if (existingObject.Count == 1)
    {
        var requestCopyObject = new CopyObjectRequest()
        {
            SourceBucket = BucketNameProd,
            SourceKey = objectToMerge.Key,
            DestinationBucket = BucketNameDev,
            DestinationKey = newKey
        };
        client.CopyObject(requestCopyObject);
    }
}

con il cliente che è qualcosa di simile

var config = new AmazonS3Config { CommunicationProtocol = Protocol.HTTP, ServiceURL = "s3-eu-west-1.amazonaws.com" };
var client = AWSClientFactory.CreateAmazonS3Client(AWSAccessKey, AWSSecretAccessKey, config);

Potrebbe esserci un modo migliore, ma è solo un codice veloce che ho scritto per trasferire alcuni file.


1
Sembra una buona soluzione. ma cosa succede se hai credenziali diverse per i 2 bucket?
Roee Gavirel,

2
Le credenziali sono per l'esecuzione del comando di copia. Quelle singole credenziali richiedono autorizzazioni di lettura / scrittura appropriate nei bucket di origine / destinazione. Per copiare tra account, è necessario utilizzare una policy del bucket per consentire l'accesso al bucket dalle credenziali dell'altro account.
Matt Houser

9

Se disponi di un host unix in AWS, utilizza s3cmd da s3tools.org. Imposta le autorizzazioni in modo che la tua chiave abbia accesso in lettura al tuo bucket di sviluppo. Quindi esegui:

s3cmd cp -r s3://productionbucket/feed/feedname/date s3://developmentbucket/feed/feedname

Lato server? Non esiste un lato server per s3. Tutti i comandi vengono eseguiti da un client remoto.
dk.

A proposito, questo comando sembra funzionare bene su Internet!
Gabe Kopley

3
La domanda "lato server" è valida. Il s3cmd trasferisce tutti i dati al client o è un trasferimento diretto da S3 a S3? Nel primo caso, sarebbe preferibile eseguirlo nel cloud AWS per evitare i trasferimenti WAN esterni.
Bruce Edge

1
La copia avviene tutto da remoto su S3.
dk.

Si noti inoltre che se si interrompe accidentalmente questo processo s3cmd cpnon si accetta l' --skip-existingopzione, è comunque possibile eseguire s3cmd syncinvece con salta esistente
ianstarz

9

Per me il seguente comando ha funzionato:

aws s3 mv s3://bucket/data s3://bucket/old_data --recursive

2
soluzione semplice e diretta ... perché utilizzare strumenti di terze parti o soluzioni alternative per attività così semplici quando questo può essere fatto con aws cli ?!
Fr0zenFyr

7

Ecco una classe Ruby per eseguire questa operazione: https://gist.github.com/4080793

Utilizzo di esempio:

$ gem install aws-sdk
$ irb -r ./bucket_sync_service.rb
> from_creds = {aws_access_key_id:"XXX",
                aws_secret_access_key:"YYY",
                bucket:"first-bucket"}
> to_creds = {aws_access_key_id:"ZZZ",
              aws_secret_access_key:"AAA",
              bucket:"first-bucket"}
> syncer = BucketSyncService.new(from_creds, to_creds)
> syncer.debug = true # log each object
> syncer.perform

5

In realtà, di recente utilizzo solo l'azione copia + incolla nell'interfaccia di AWS s3. Vai ai file che desideri copiare, fai clic su "Azioni" -> "Copia", quindi vai al bucket di destinazione e "Azioni" -> "Incolla"

Trasferisce i file abbastanza velocemente e sembra una soluzione meno contorta che non richiede alcuna programmazione o soluzioni sopra le righe come quella.


Sì. L'ho scoperto qualche minuto fa. Ho votato positivamente, quindi più persone risparmieranno tempo :)
JCarlosR

L'ho provato su una copia da secchio a secchio con 134.364 oggetti al suo interno. Ci sono volute ore. E la destinazione si è conclusa con solo 134.333 file: la copia diceva che era "riuscito", ma non c'era alcuna spiegazione per i file mancanti.
warrens

Utilizzando il comando di tipo "aws s3 sync" descritto in altri post qui, tutti i 134.364 oggetti sono stati copiati in circa 20 minuti.
warrens

4

Abbiamo avuto questo problema esatto con i nostri lavori ETL su Snowplow , quindi abbiamo estratto il nostro codice di copia file parallela (Ruby, costruito su Fog ), nella sua gemma Ruby, chiamata Sluice:

https://github.com/snowplow/sluice

Sluice gestisce anche l'eliminazione, lo spostamento e il download di file S3; tutto parallelizzato e con riprova automatica se un'operazione fallisce (cosa che fa sorprendentemente spesso). Spero sia utile!



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.