6

私の会社は、大きなアーカイブ ファイルを S3 にアップロードしており、S3 で解凍したいと考えています。xxx-zip バケットへのファイルの到着によってトリガーされる unzip に基づくラムダ関数を作成しました。この関数は、S3 から zip ファイルをストリーミングし、ストリームを解凍し、個々のファイルを xxx-data バケットにストリーミングします。

動作しますが、予想よりもはるかに遅いことがわかりました.zipサイズが約500kで、約500個のファイルを保持しているテストファイルでも、60秒のタイムアウトが設定されているとタイムアウトします。これは正しいと思いますか?ノードで実行されているローカル システムでは、これよりも高速です。ファイルは Amazon のクラウド内で移動されているため、待ち時間は短く、ファイルがストリーミングされているため、実際にかかる時間はストリームを解凍するのにかかる時間とほぼ同じになるはずです。

これが機能しない固有の理由がありますか、それとも私のコードに非常に遅くなる原因がありますか? node.js を使用するのは初めてなので、何か悪いことをしている可能性があります。または、Googleで見つけられなかったこれを行うためのより良い方法はありますか?

コードの概要は次のとおりです (によって返されたBufferStreamBuffer を にラップする、私が作成したクラスです)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, '');
        }
    });
}
4

1 に答える 1

3

使用している解凍モジュールは、zip ファイルを解凍できる JavaScript 実装であると思われますが、これは非常に低速です。

gzip を使用してファイルを圧縮し、C でコンパイルされた内部zlibライブラリを使用することをお勧めします。これにより、パフォーマンスが大幅に向上します。

zip を使用することを選択した場合は、Amazon サポートに連絡して、ラムダ関数の 60 秒の制限を増やすよう依頼することができます。

于 2015-02-22T19:31:42.833 に答える