从AWS Lambda Node.JS流式传输并压缩到S3

时间:2017-10-18 14:45:58

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

我的目标是创建一个大型的gzip压缩文本并将其放入S3。

文件内容由我从其他来源循环读取的块组成。

由于此文件的大小,我无法将所有数据保存在内存中,因此我需要以某种方式将其直接流式传输到S3和ZIP。

我理解如何在Node.JS中使用常规fs来执行此技巧,但我很困惑,是否可以使用AWS Lambda中的S3执行相同的技巧?我知道s3.putObject can consume streamObject,但在我看来,当我执行putObject操作时,此流应该已经完成​​,这会导致超出允许的内存。

1 个答案:

答案 0 :(得分:3)

您可以使用NodeJs multipart upload functions中的aws-sdk将文件(> 5mb)流式传输到S3存储桶中。

这不仅可以将大型文件流式传输到存储桶中,还可以让您重试失败的块(而不是整个文件)和并行化上传各个块(有多个,上传lambda,例如,在无服务器ETL设置中可能很有用)。只要您跟踪它们并在上传所有流程后完成流程,它们到达的顺序并不重要。

要使用分段上传,您应该:

  1. 使用createMultipartUpload初始化流程并存储返回的UploadId(您需要将其用于块上传)
  2. 实现一个Transform流,用于处理来自输入流的数据
  3. 实施一个PassThrough流,在使用uploadPart将数据推送到S3(在步骤1中返回的UploadId下)之前,将足够大的数据块缓冲数据
  4. 跟踪从块上传中返回的ETagsPartNumbers
  5. 使用跟踪的ETagsPartNumbers使用completeMultipartUpload
  6. 在S3上汇编/完成文件

    这是工作代码示例中的gist of it,它从iso.org流式传输文件,通过gzip传输到S3存储桶。不要忘记更改存储桶名称,并确保在节点6.10上运行带有512mb内存的lambda。您可以直接在Web GUI中使用代码,因为没有外部依赖项。

    注意:这只是我为了演示目的而放在一起的概念证明。对于失败的块上传没有重试逻辑,并且几乎不存在错误处理,这可能会花费您的成本(例如,在取消整个过程以清理上载的块时应调用abortMultipartUpload,因为它们仍然存储并且 S3上不可见,即使最终文件从未组装过)。正在暂停输入流,而不是使用backpressure流机制等排队上传作业。