использование лямбда-функций для распаковки архивов в S3 - это действительно sloooooow
Моя компания загружает большие архивные файлы на S3 и теперь хочет, чтобы они были разархивированы на S3. Я написал лямбда-функцию, основанную на распаковке, вызванную поступлением файла в корзину xxx-zip, которая передает поток zip-файлов из S3, распаковывает поток и затем передает отдельные файлы в корзину xxx-data.
Это работает, но я нахожу, что это намного медленнее, чем я ожидаю - даже для тестового файла, размер почтового индекса около 500 КБ и около 500 файлов, это время ожидания с 60-секундным тайм-аутом. Это кажется правильным? В моей локальной системе, работающей с узлом, это быстрее, чем это. Мне кажется, что поскольку файлы перемещаются внутри облака Amazon, задержка должна быть короткой, а поскольку файлы передаются в потоковом режиме, фактическое время, которое требуется, должно быть примерно таким, как требуется, чтобы разархивировать поток.
Есть ли врожденная причина, почему это не сработает, или в моем коде есть что-то, что заставляет его работать так медленно? Я впервые работаю с node.js, поэтому могу что-то делать плохо. Или есть лучший способ сделать это, что я не мог найти с Google?
Вот набросок кода (BufferStream
это класс, который я написал, который оборачивает Buffer, возвращаемыйs3.getObject()
в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, '');
}
});
}