2013-10-10 18 views
10

Ho alcuni file che vengono caricati su S3 ed elaborati per alcune attività di Redshift. Dopo che l'attività è completata, questi file devono essere uniti. Attualmente sto cancellando questi file e caricando nuovamente i file uniti. Questi consumano molta banda. C'è un modo in cui i file possono essere uniti direttamente su S3?Unione di file su AWS S3 (utilizzando Apache Camel)

Sto usando Apache Camel per il routing.

risposta

20

S3 consente di utilizzare un URI di file S3 come origine per un'operazione di copia. In combinazione con l'API di caricamento di più parti di S3, è possibile fornire diversi URI di oggetti S3 as the sources keys per un caricamento multiparte.

Tuttavia, il diavolo è nei dettagli. L'API di caricamento multiparte di S3 ha una dimensione minima della parte del file di 5 MB. Quindi, se qualsiasi file nella serie di file sotto concatenazione è < 5 MB, fallirà.

Tuttavia, è possibile aggirare questo sfruttando il foro del loop che consente al pezzo di caricamento finale di essere < 5 MB (consentito perché questo accade nel mondo reale quando si caricano i pezzi rimanenti).

mio codice di produzione fa questo:

  1. Interrogazione del manifesto di file da caricare
  2. Se prima parte è sotto 5MB, scaricare pezzi * e tampone a disco fino a 5 MB è tamponato.
  3. Accoda le parti in sequenza fino al completamento della concatenazione di file
  4. Se un file non terminus è < 5 MB, aggiungerlo, quindi completare il caricamento e creare un nuovo caricamento e continuare.

Infine, c'è un errore nell'API S3. L'ETag (che in realtà è un qualsiasi checksum di file MD5 su S3, non viene ricalcolato correttamente al completamento di un caricamento multiparte. Per risolvere questo problema, copia l'ammenda al completamento.Se si utilizza una posizione temporanea durante la concatenazione, questa verrà risolta sul funzionamento finale di copia.

* si noti che è possibile scaricare una byte range of a file. in questo modo, se la parte 1 è 10K, e parte 2 è 5GB, avete solo bisogno di leggere 5110K per ottenere soddisfare la dimensione 5 MB necessaria per continuare .

** si potrebbe anche avere un blocco 5 MB di zeri su S3 e usarlo come predefinito a partire pezzo. Poi, quando il caricamento è completo, fare una copia del file con intervallo di byte di 5MB+1 to EOF-1

P.S. Quando avrò il tempo di fare un Gist di questo codice, posterò il link qui.

+1

Questa è davvero una bella risposta! Ho intenzione di implementarlo per creare dinamicamente i file zip come menzionato in [questo post del blog] (http://www.w2lessons.com/2012/01/fast-zipping-in-amazon-s3.html). Sto anche pensando di creare un pool di lavoro con AWS Lambda per elaborare la richiesta più rapidamente evitando la limitazione della velocità S3. – MadMod

+0

@MadMod Non sono sicuro che il formato Zip lo consenta tramite la concatenazione diretta dei file zip. Avrai almeno bisogno di aggiornare le dimensioni e le intestazioni CRC dello zip esistente dopo la concatenazione. –

+0

@JosephLust, c'è qualche possibilità che tu possa condividere Gist? – Blexy

-6

S3 è un'archiviazione di oggetti, non un'archiviazione di blocchi. Devi recuperare l'oggetto (i) prima di poterlo manipolare/loro.

Quindi, la risposta è: No. Non è possibile unire direttamente i file su S3.

+2

Questo non è sempre preciso.Fintanto che tutti i file tranne uno sono almeno 5 MB, puoi usare multipart con copia come indicato sotto – bridiver

+0

Dovrebbero essere 5 GB (non 5 MB)? –

+0

No, i suoi 5 MB per la dimensione minima della parte (eccetto per l'ultima parte che può essere più piccola). –

14

È possibile utilizzare Multipart Upload with Copy per unire oggetti su S3 senza scaricarli e caricarli nuovamente.

È possibile trovare alcuni esempi in Java, .NET o con l'API REST here.