Node.js 通过lambda nodejs(流媒体)从AWS RDS(SQL Server)到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已执行查询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上传流
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);
我错过了什么
谢谢这对我来说在本地有效,但在云中上传对我来说根本没有发生-对我可能发生的事情有任何想法吗?这对我来说在本地有效,但在云中上传对我来说根本没有发生-对我可能发生的事情有任何想法吗?