Il modo più efficiente per eliminare in batch i file S3


16

Mi piacerebbe poter eliminare in batch migliaia o decine di migliaia di file contemporaneamente su S3. Ogni file dovrebbe essere compreso tra 1 MB e 50 MB. Naturalmente, non voglio che l'utente (o il mio server) sia in attesa mentre i file sono in procinto di essere eliminati. Quindi, le domande:

  1. In che modo S3 gestisce la cancellazione dei file, specialmente quando si eliminano grandi quantità di file?
  2. Esiste un modo efficace per farlo e fare in modo che AWS esegua la maggior parte del lavoro? Per efficienza, intendo effettuando il minor numero di richieste a S3 e impiegando il minor tempo possibile utilizzando la minima quantità di risorse sui miei server.

Risposte:


12

AWS supporta l'eliminazione in blocco di un massimo di 1000 oggetti per richiesta utilizzando l'API REST S3 e i suoi vari wrapper. Questo metodo presuppone che tu conosca le chiavi dell'oggetto S3 che vuoi rimuovere (ovvero, non è progettato per gestire qualcosa come una politica di conservazione, file che superano una certa dimensione, ecc.).

L'API REST S3 può specificare fino a 1000 file da eliminare in una singola richiesta, il che deve essere più rapido rispetto alle singole richieste. Ricorda, ogni richiesta è una richiesta HTTP (quindi TCP). Quindi ogni richiesta comporta spese generali. Devi solo conoscere le chiavi degli oggetti e creare una richiesta HTTP (o utilizzare un wrapper nella tua lingua preferita). AWS fornisce ottime informazioni su questa funzione e sul suo utilizzo . Basta scegliere il metodo con cui ti senti più a tuo agio!

Suppongo che il tuo caso d'uso coinvolga gli utenti finali specificando un numero di file specifici da eliminare contemporaneamente. Anziché avviare un'attività come "Elimina tutti gli oggetti che fanno riferimento a file di immagini" o "Elimina tutti i file più vecchi di una determinata data" (che credo sia facile da configurare separatamente in S3).

In tal caso, saprai le chiavi che devi eliminare. Significa anche che l'utente apprezzerà più feedback in tempo reale sul fatto che il suo file sia stato eliminato correttamente o meno. I riferimenti a chiavi esatte dovrebbero essere molto rapidi, poiché S3 è stato progettato per scalare in modo efficiente nonostante gestisca una quantità estremamente elevata di dati.

In caso contrario, puoi esaminare le chiamate API asincrone. Puoi leggere un po 'di come funzionerebbero in generale da questo post sul blog o cercare come farlo nella lingua che preferisci . Ciò consentirebbe alla richiesta di eliminazione di occupare il proprio thread e il resto del codice può essere eseguito senza che l'utente attenda. In alternativa, è possibile scaricare la richiesta in una coda. . . Ma entrambe queste opzioni complicano inutilmente il tuo codice (il codice asincrono può essere fastidioso) o il tuo ambiente (avresti bisogno di un servizio / daemon / container / server per gestire la coda. Quindi eviterei questo scenario se possibile.

Modifica: non ho la reputazione di pubblicare più di 2 link. Ma puoi vedere i commenti di Amazon sul tasso di richieste e le prestazioni qui: http://docs.aws.amazon.com/AmazonS3/latest/dev/request-rate-perf-considerations.html E le faq s3 commentano che il deleiton in blocco è il strada da percorrere se possibile.


17

L' opzione estremamente lenta è s3 rm --recursivese ti piace davvero aspettare.

L'esecuzione in parallelo s3 rm --recursivecon --includemodelli diversi è leggermente più veloce ma è ancora molto tempo in attesa, poiché ogni processo recupera singolarmente l'intero elenco di chiavi per eseguire localmente la --includecorrispondenza dei modelli.

Inserisci la cancellazione collettiva.

Ho scoperto che ero in grado di ottenere la massima velocità eliminando 1000 tasti alla volta usando aws s3api delete-objects.

Ecco un esempio:

cat file-of-keys | xargs -P8 -n1000 bash -c 'aws s3api delete-objects --bucket MY_BUCKET_NAME --delete "Objects=[$(printf "{Key=%s}," "$@")],Quiet=true"' _
  • L' -P8opzione su xargscontrolla il parallelismo. Sono otto in questo caso, ovvero 8 istanze di 1000 eliminazioni alla volta.
  • L' -n1000opzione indica xargsdi raggruppare 1000 chiavi per ogni aws s3api delete-objectschiamata.
  • Rimuovendolo ,Quiet=trueo modificandolo, falseverranno emesse le risposte del server.
  • Nota: c'è facilmente perdere _alla fine di quella riga di comando. @VladNikiforov ha pubblicato un eccellente commento di cosa serve nel commento, quindi mi limiterò a collegarmi a questo.

Ma come si ottiene file-of-keys?

Se hai già la tua lista di chiavi, buona per te. Lavoro completato.

In caso contrario, ecco un modo immagino:

aws s3 ls "s3://MY_BUCKET_NAME/SOME_SUB_DIR" | sed -nre "s|[0-9-]+ [0-9:]+ +[0-9]+ |SOME_SUB_DIR|p" >file-of-keys

9
Ottimo approccio, ma ho scoperto che elencare le chiavi era il collo di bottiglia. Questo è molto più veloce: aws s3api list-objects --output text --bucket BUCKET --query 'Contents[].[Key]' | pv -l > BUCKET.keys E quindi rimuovere gli oggetti (questo era sufficiente che il superamento di 1 processo parallelo raggiungesse i limiti di velocità per l'eliminazione degli oggetti): tail -n+0 BUCKET.keys | pv -l | grep -v -e "'" | tr '\n' '\0' | xargs -0 -P1 -n1000 bash -c 'aws s3api delete-objects --bucket BUCKET --delete "Objects=[$(printf "{Key=%q}," "$@")],Quiet=true"' _
SEK

2
Probabilmente avresti dovuto anche sottolineare l'importanza _alla fine :) L'ho perso e poi mi ci è voluto un po 'di tempo per capire perché il primo elemento viene saltato. Il punto è che bash -cpassa tutti gli argomenti come parametri posizionali, a partire da $0, mentre "$ @" elabora solo i parametri che iniziano con $1. Quindi il carattere di sottolineatura è necessario per riempire la posizione di $0.
Vlad Nikiforov,

@VladNikiforov Cheers, modificato.
antak

3
Un problema che ho riscontrato con questo approccio (da Antak o Vlad) è che non è facilmente ripristinabile in caso di errore. Se stai eliminando molte chiavi (nel mio caso 10 M) potresti avere un errore di rete, o un errore di limitazione, che interrompe questo. Quindi, per migliorare questo, ho usato split -l 1000per dividere il mio file di chiavi in ​​1000 lotti di chiavi. Ora per ogni file posso emettere il comando delete quindi eliminare il file. Se qualcosa va storto, posso continuare.
joelittlejohn,

Se vuoi solo un elenco delle chiavi, penso che aws s3 ls "s3://MY_BUCKET_NAME/SOME_SUB_DIR" | awk '{print $4}'sarebbe più semplice e puoi aggiungere un | grepper filtrarlo da lì.
Hayden,

3

Sono stato frustrato dalle prestazioni della console Web per questo compito. Ho scoperto che il comando CLI AWS fa bene. Per esempio:

aws s3 rm --recursive s3://my-bucket-name/huge-directory-full-of-files

Per una gerarchia di file di grandi dimensioni, ciò potrebbe richiedere un tempo considerevole. Puoi impostarlo in esecuzione in una tmuxo screensessione e ricontrollare più tardi.


2
Sembra che il aws s3 rm --recursivecomando elimini i file singolarmente. Anche se più veloce della console Web, quando si eliminano molti file, potrebbe essere molto più veloce se eliminato in blocco
Brandon,


0

Senza sapere come stai gestendo le benne s3, questo può o meno essere particolarmente utile.

Gli strumenti della CLI AWS hanno un'opzione chiamata "sync" che può essere particolarmente efficace per garantire che s3 abbia gli oggetti corretti. Se tu oi tuoi utenti gestite S3 da un filesystem locale, potreste essere in grado di risparmiare un sacco di lavoro determinando quali oggetti devono essere eliminati usando gli strumenti della CLI.

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


0

Si parla già di s3 synccomando prima, ma senza esempio e parola --deletesull'opzione.

Ho trovato il modo più veloce per eliminare il contenuto della cartella nel S3bucket my_bucketda:

aws s3 sync --delete "local-empty-dir/" "s3://my_bucket/path-to-clear"

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.