La mia azienda carica file di archivio di grandi dimensioni su S3 e ora vuole che vengano decompressi su S3. Ho scritto una funzione lambda basata su unzip, innescata dall'arrivo di un file nel bucket xxx-zip, che esegue lo streaming del file zip da S3, decomprime lo stream e quindi trasferisce i singoli file nel bucket xxx-data.l'uso delle funzioni lambda per decomprimere gli archivi in S3 è veramente veloce.
Funziona, ma trovo che è molto più lento di quanto mi aspetto - anche su un file di test, dimensione zip di circa 500k e contenente circa 500 file, questo è il timeout con un set di timeout di 60 secondi. Questo sembra giusto? Sul mio sistema locale in esecuzione con il nodo è più veloce di questo. Mi sembra che, dal momento che i file vengono spostati all'interno della nuvola di Amazon, la latenza dovrebbe essere breve, e dal momento che i file vengono trasmessi in streaming, il tempo effettivo impiegato dovrebbe essere il tempo necessario per decomprimere il flusso.
C'è un motivo intrinseco per cui questo non funzionerà, o c'è qualcosa nel mio codice che sta causando così lento? È la prima volta che lavoro con node.js, quindi potrei fare qualcosa di male. O c'è un modo migliore per farlo che non potrei trovare con google?
Ecco una descrizione del codice (BufferStream
è una classe che ho scritto che avvolge il buffer restituito da s3.getObject()
in una readStream
)
var aws = require('aws-sdk');
var s3 = new aws.S3({apiVersion: '2006-03-01'});
var unzip = require('unzip');
var stream = require('stream');
var util = require("util");
var fs = require('fs');
exports.handler = function(event, context) {
var zipfile = event.Records[0].s3.object.key;
s3.getObject({Bucket:SOURCE_BUCKET, Key:zipfile},
function(err, data) {
var errors = 0;
var total = 0;
var successful = 0;
var active = 0;
if (err) {
console.log('error: ' + err);
}
else {
console.log('Received zip file ' + zipfile);
new BufferStream(data.Body)
.pipe(unzip.Parse()).on('entry', function(entry) {
total++;
var filename = entry.path;
var in_process = ' (' + ++active + ' in process)';
console.log('extracting ' + entry.type + ' ' + filename + in_process);
s3.upload({Bucket:DEST_BUCKET, Key: filename, Body: entry}, {},
function(err, data) {
var remaining = ' (' + --active + ' remaining)';
if (err) {
// if for any reason the file is not read discard it
errors++
console.log('Error pushing ' + filename + ' to S3' + remaining + ': ' + err);
entry.autodrain();
}
else {
successful++;
console.log('successfully wrote ' + filename + ' to S3' + remaining);
}
});
});
console.log('Completed, ' + total + ' files processed, ' + successful + ' written to S3, ' + errors + ' failed');
context.done(null, '');
}
});
}
Grazie per il suggerimento. Sto cercando di farlo con zlib per confrontare i tempi, ma ho riscontrato un problema con il caricamento su S3 (http://stackoverflow.com/questions/28688490/untarring-files-to-s3-fails-non-sure-why) – russell
Dopo aver misurato più misure, ho scoperto che è la dimensione dei file, e non il numero, a causare problemi. Se l'archivio conteneva un file di testo da 5 MB che da solo impiegava la maggior parte del tempo. Quindi sembra che questo non sia il modo giusto per farlo. Lo scriverò sul sondaggio EC2 da SQS. – russell