5

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

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

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

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

4

1 回答 1

7

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

这不仅对于将大文件流式传输到存储桶中很有用,而且还使您能够重试失败的块(而不是整个文件)并并行上传单个块(使用多个上传 lambda,这在无服务器 ETL 设置中可能很有用)例子)。只要您跟踪它们并在全部上传后完成流程,它们到达的顺序并不重要。

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

  1. createMultipartUpload使用并存储返回的过程初始化过程UploadId(您需要它来进行块上传)
  2. 实现一个转换流来处理来自输入流的数据
  3. 实现一个PassThroughuploadPart流,该流将在将数据推送到 S3之前以足够大的块缓冲数据(UploadId在步骤 1 中返回的情况下)
  4. 跟踪返回的ETagsPartNumbers从块上传
  5. 使用跟踪ETagsPartNumbers使用在 S3 上组装/完成文件completeMultipartUpload

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

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

于 2017-10-19T14:28:45.927 回答