我的目标是创建一个大型的gzip压缩文本并将其放入S3。
文件内容由我从其他来源循环读取的块组成。
由于此文件的大小,我无法将所有数据保存在内存中,因此我需要以某种方式将其直接流式传输到S3和ZIP。
我理解如何在Node.JS中使用常规fs
来执行此技巧,但我很困惑,是否可以使用AWS Lambda中的S3执行相同的技巧?我知道s3.putObject
can consume streamObject
,但在我看来,当我执行putObject
操作时,此流应该已经完成,这会导致超出允许的内存。
答案 0 :(得分:3)
您可以使用NodeJs multipart upload functions中的aws-sdk将文件(> 5mb)流式传输到S3存储桶中。
这不仅可以将大型文件流式传输到存储桶中,还可以让您重试失败的块(而不是整个文件)和并行化上传各个块(有多个,上传lambda,例如,在无服务器ETL设置中可能很有用)。只要您跟踪它们并在上传所有流程后完成流程,它们到达的顺序并不重要。
要使用分段上传,您应该:
createMultipartUpload
初始化流程并存储返回的UploadId
(您需要将其用于块上传)uploadPart
将数据推送到S3(在步骤1中返回的UploadId
下)之前,将足够大的数据块缓冲数据ETags
和PartNumbers
ETags
和PartNumbers
使用completeMultipartUpload
这是工作代码示例中的gist of it,它从iso.org流式传输文件,通过gzip传输到S3存储桶。不要忘记更改存储桶名称,并确保在节点6.10上运行带有512mb内存的lambda。您可以直接在Web GUI中使用代码,因为没有外部依赖项。
注意:这只是我为了演示目的而放在一起的概念证明。对于失败的块上传没有重试逻辑,并且几乎不存在错误处理,这可能会花费您的成本(例如,在取消整个过程以清理上载的块时应调用abortMultipartUpload
,因为它们仍然存储并且 S3上不可见,即使最终文件从未组装过)。正在暂停输入流,而不是使用backpressure流机制等排队上传作业。