node.js - 使用 lambda 函数在 S3 中解压缩文件真的很慢

标签 node.js amazon-web-services amazon-s3 aws-lambda

我的公司正在将大型存档文件上传到 S3,现在希望它们在 S3 上解压缩。我写了一个基于 unzip 的 lambda 函数,由文件到达 xxx-zip 桶触发,它从 S3 流式传输 zip 文件,解压缩流,然后将单个文件流式传输到 xxx-data 桶。

它有效,但我发现它比我预期的要慢得多 - 即使在测试文件上,zip 大小约为 500k 并包含大约 500 个文件,这是超时设置 60 秒。这看起来对吗?在我运行 Node 的本地系统上,它比这更快。在我看来,由于文件正在 Amazon 的云中移动,延迟应该很短,并且由于文件正在流式传输,因此实际花费的时间应该大约是解压缩流所需的时间。

是否存在无法运行的内在原因,或者是我的代码中有什么东西导致速度如此之慢?这是我第一次使用 node.js,所以我可能会做一些糟糕的事情。或者是否有更好的方法来执行此操作,而我在 google 上找不到?

这里是代码的大纲(BufferStream是我写的一个类,将s3.getObject()返回的Buffer包装成一个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, '');
        }
    });
}

最佳答案

我怀疑您正在使用的解压缩模块是一个允许您解压缩 zip 文件的 JavaScript 实现 - 这非常慢。

我推荐使用gzip压缩文件 并使用内部 zlib C 编译的库,应该提供更好的性能。

如果您选择坚持使用 zip,您可以联系亚马逊支持并要求增加 lambda 函数的 60 秒限制。

关于node.js - 使用 lambda 函数在 S3 中解压缩文件真的很慢,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28659067/

相关文章:

node.js - 如何使用 NodeJS 加密来签署文件?

java - 使用 Java 查找我所有 EC2 实例的公共(public) IP?

docker - 具有Docker支持的EMR 6 Beta具有S3访问问题

node.js - 在 Node Express 应用程序中显示私有(private) S3 图像

node.js - 如何部署 Angular.js 应用程序?

node.js - 如何在 Jade 中评估助手而不输出其结果?

node.js - --be_ip 参数来自命令 : nohup nodejs server. js 从哪里来?

amazon-web-services - 在 Windows Server 2012 AWS EC2 实例上无需停机即可获得一致的 EBS 快照

amazon-web-services - 如何自动停止和启动 AWS EC2 实例

c# - 如何使用 C# 将容器及其内容复制到 AWS 存储桶?