Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/amazon-s3/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Node.js 通过lambda nodejs(流媒体)从AWS RDS(SQL Server)到S3存储桶_Node.js_Amazon S3_Stream_Aws Lambda - Fatal编程技术网

Node.js 通过lambda nodejs(流媒体)从AWS RDS(SQL Server)到S3存储桶

Node.js 通过lambda nodejs(流媒体)从AWS RDS(SQL Server)到S3存储桶,node.js,amazon-s3,stream,aws-lambda,Node.js,Amazon S3,Stream,Aws Lambda,我尝试通过csv stringify转换将一些SQL Server数据(aws rds)下载到S3存储桶时遇到了一些麻烦 我在nodejs 8.10中使用lambda函数 由于下载的记录可能有几百万条,我必须使用streams,否则我将无法将记录集存储在内存中 因此,我有一个SQL请求req、一个字符串化器和一个名为uplaod的s3上传流stram 我还尝试了s3流,结果是一样的:当记录数超过大约200K时,我出现了一个最大内存错误 我添加了一些日志,试图了解发生了什么,并发现问题是s3上传流

我尝试通过csv stringify转换将一些SQL Server数据(aws rds)下载到S3存储桶时遇到了一些麻烦

我在nodejs 8.10中使用lambda函数

由于下载的记录可能有几百万条,我必须使用streams,否则我将无法将记录集存储在内存中

因此,我有一个SQL请求req、一个字符串化器和一个名为uplaod的s3上传流stram

我还尝试了s3流,结果是一样的:当记录数超过大约200K时,我出现了一个最大内存错误

我添加了一些日志,试图了解发生了什么,并发现问题是s3上传流(与s3流相同)在我关闭流之前不会发送部分,将所有内容都保留在内存中

以下是我从日志中得到的信息:

2019-03-19T16:09:31.995Z已执行查询
2019-03-19T16:09:32.092Z S3缓冲设置为5242880 x 1
2019-03-19T16:09:32.113Z正在运行的流
2019-03-19T16:09:37.933Z已处理记录:10000可用内存:70750208
2019-03-19T16:09:40.494Z已处理记录:20000可用内存:64368640
2019-03-19T16:09:43.492Z已处理记录:30000可用内存:78753792
2019-03-19T16:09:45.652Z已处理记录:40000可用内存:75481088
2019-03-19T16:09:47.952Z已处理记录:50000可用内存:72622080
2019-03-19T16:09:50.853Z已处理记录:60000可用内存:68972544
2019-03-19T16:09:53.013Z已处理记录:70000可用内存:67604480
2019-03-19T16:09:55.193Z已处理记录:80000可用内存:64204800
2019-03-19T16:09:57.933Z已处理记录:90000可用内存:80928768
2019-03-19T16:10:00.152Z已处理记录:100000可用内存:79167488
2019-03-19T16:10:02.392Z已处理记录:110000可用内存:76013568
2019-03-19T16:10:05.292Z已处理记录:120000可用内存:73478144
2019-03-19T16:10:07.572Z已处理记录:130000可用内存:73641984
2019-03-19T16:10:10.852Z已处理记录:140000可用内存:72503296
2019-03-19T16:10:14.053Z已处理记录:150000可用内存:69713920
2019-03-19T16:10:14.074Z架线机完成
2019-03-19T16:10:16.012Z书写s3部分
2019-03-19T16:10:16.013Z{ETag:'a4e3140f5d17fab9b3ccff9561a05730',
零件号:1,
接收大小:5242880,
上传大小:5242880}
2019-03-19T16:10:16.204Z写s3部分
2019-03-19T16:10:16.204Z{ETag:“'30c90f1880190bea1fc9b5e1e7a1286d”, 零件号:2,
接收大小:5530146,
上传大小:5530146}
2019-03-19T16:10:16.401Z{ServerSideEncryption:'AES256',
位置:“”,
Bucket:'mybucket',
关键字:“foldername/lambdaTest.csv”,
ETag:“553D792791F047633D04503F92A9281-2”}
结束请求ID: 报告请求ID:持续时间:45686.58毫秒内存大小:128 MB最大使用内存:117 MB

正如您所看到的,我可以每2.5秒下载大约10000条记录,但是s3流只有在我关闭stringify之后才会调用part事件

以下是我的代码设置:

req.stream = true; 
req.query(sql);    

if (__DEBUG) console.log("query executed");
upload = s3Stream.upload(s3params);

console.log("S3 Buffering is set to "+s3BufLen+" x "+s3ConcurrentBuffers);
upload.concurrentParts(s3ConcurrentBuffers); // limit to x buffers
upload.on('part', function (details) {
            if (__DEBUG){
                console.log("writing s3 part");
                console.log(details);
             }
 });

upload.on('uploaded', function (details) {
                    console.log(details);
                    mssql.close();
                    callback(null,details);
});

var stringifier = stringify(csvOptions);

stringifier.on('finish', function(){
                          if (__DEBUG) console.log("stringifier done");
                          upload.end();
                     });

stringifier.on('readable', function()
                          {
                            let row;
                            while(row = stringifier.read())
                            {
                               if (__DEBUG && (++processed % 10000 == 0)) console.log("Processed records : "+processed+
                                  " Available memory : "+ os.freemem());
                                upload.write(row); 
                            }
                          });

req.pipe(stringifier); //.pipe(upload);
我暂时“取消管道”上传流,并添加了stringifier.on处理程序,以更好地调试流程

我所期望的是,上传流的部分事件在遇到每5MB块时被调用,而在我关闭流后,所有的块显然都被刷新

注意,我还将upload.concurrentParts(…)强制为1,但没有效果

更新:

我看到s3 upload streams模块被认为是不推荐使用的,它建议改用s3.upload(来自AWS SDK),这确实改进了一些东西-它使用的内存更少-但并没有完全解决我的问题,内存消耗仍然随着部件数量的增加而增加

这就是我修改代码的方式:

    var upload = new stream.PassThrough(), 
    s3options = {partSize: s3BufLen, queueSize: s3ConcurrentBuffers};

    s3params.Body = upload;

    s3.upload(s3params, s3options, function(err, data) {
              console.log(err, data);
              mssql.close();
              callback(err,data);
    });

    req.pipe(stringifier).pipe(upload);
我错过了什么


谢谢

这对我来说在本地有效,但在云中上传对我来说根本没有发生-对我可能发生的事情有任何想法吗?这对我来说在本地有效,但在云中上传对我来说根本没有发生-对我可能发生的事情有任何想法吗?