从AWS Lambda Node.JSstream式传输到S3

我的目标是创build一个大的gzip文本文件,并将其放入S3。

文件内容由我从另一个源代码循环读取的块组成。

由于这个文件的大小,我不能保存所有的数据在内存中,所以我需要以某种方式直接stream到S3和ZIP在同一时间。

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

您可以使用NodeJs aws-sdk中的分段上传function将文件(> 5mb)以块的formsstream式传输到S3存储桶中。

这不仅适用于将大文件传输到存储桶中,而且还可以重试失败的块(而不是整个文件),并且可以并行上传单个块(带有多个上传的lambda,这对于无服务器的ETL设置可能有用例)。 只要你跟踪它们并且一旦所有的上传完成,它们到达的顺序并不重要。

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

  1. 使用createMultipartUpload初始化该进程并存储返回的UploadId (您将需要它用于块上载)
  2. 实现一个处理来自inputstream的数据的Transformstream
  3. 在使用uploadPart将它们推送到S3(在步骤1中返回的UploadId下)之前实现一个PassThroughstream,该stream将缓冲足够大的块中的数据,
  4. 跟踪从块上载返回的ETagsPartNumbers
  5. 使用跟踪的ETagsPartNumbers使用completeMultipartUpload在S3上组合/结束文件

下面是一个工作代码示例中的要点,该示例从iso.orgstream式传输文件,通过gzip将其传输到S3存储桶中。 不要忘记更改存储桶名称,并确保在节点6.10上运行内存为512mb的lambda。 您可以直接在Web GUI中使用代码,因为没有外部依赖关系。

注意 :这仅仅是为了演示目的而放在一起的一个概念certificate。 没有失败的块上传的重试逻辑,error handling几乎不存在,这可能会花费你的成本(例如,取消整个过程来清理上传的块,因为它们保持存储在S3上并且不可见abortMultipartUpload应该调用abortMultipartUpload ,即使最终文件从未汇编)。 inputstream暂停而不是排队上传作业,并利用反压stream机制等。