5

有没有办法使用 Lambda 进行 S3 文件连接?

我有 Firehose 以最长的可能间隔(15 分钟或 128mb)将数据流式传输到 S3,因此我每天有 96 个数据文件,但我想将所有数据聚合到一个每日数据文件中,以便在稍后读取数据时获得最快的性能在 Spark (EMR) 中。

我创建了一个解决方案,当 Firehose 将新文件流式传输到 S3 时,会调用 Lambda 函数。然后该函数从源存储桶中读取 (s3.GetObject) 新文件,并从目标存储桶中读取连接的每日数据文件(如果它已经与以前的每日数据一起存在,否则创建一个新文件),将两个响应主体解码为字符串,然后只需将它们加在一起并使用 s3.PutObject 写入目标存储桶(它会覆盖以前的聚合文件)。

问题是当聚合文件达到 150+ MB 时,Lambda 函数在读取两个文件时达到其 ~1500mb 内存限制,然后失败。

目前我的数据量很少,每天几百 MB-s,但这个数量在未来会呈指数增长。对我来说很奇怪 Lambda 的限制如此之低,并且已经用如此小的文件达到了它们。

或者连接 S3 数据的替代方案是什么,理想情况下由 S3 对象创建事件或以某种方式调用的计划作业,例如每天计划?

4

2 回答 2

5

您可以使用计划事件创建一个每天仅调用一次的 Lambda 函数,并且在您的 Lambda 函数中您应该使用上传部分 -不需要在 Lambda 函数上下载文件的副本。在这个线程中已经有一个例子

于 2017-05-31T12:39:19.350 回答
5

我会重新考虑你是否真的想这样做:

  • S3 成本会上升。
  • 管道复杂性会上升。
  • 从 Firehose 输入到 Spark 输入的延迟会增加。
  • 如果单个文件注入 Spark 失败(这将发生在分布式系统中),您必须围绕一个大文件进行随机播放,如果注入不是原子的,则可能将其切片,然后再次上传,所有这些都可能需要很长时间才能处理大量数据. 此时您可能会发现恢复的时间太长,以至于您不得不推迟下一次注射……</li>

相反,除非在这种情况下不可能,否则如果您使 Firehose 文件尽可能小并立即将它们发送到 Spark :

  • 您几乎可以立即归档 S3 对象,从而降低成本。
  • 数据会尽快在 Spark 中可用。
  • 如果向 Spark 中的单个文件注入失败,则需要调整的数据更少,并且如果您有自动恢复,这甚至不应该引起注意,除非某些系统始终全速运行(此时批量注入会更糟)。
  • 建立 TCP 连接和身份验证会增加少量延迟。

我对 Spark 并不特别熟悉,但一般来说,这样的“管道”解决方案将涉及:

  • Firehose 输出桶上的定期触发器或(甚至更好)事件侦听器以尽快处理输入。
  • 一个注入器/转换器,可有效地将数据从 S3 移动到 Spark。听起来 Parquet 可以帮助解决这个问题。
  • 准备好接收数据的实时 Spark/EMR/底层数据服务实例。
  • 在底层数据服务的情况下,创建新的 Spark 集群以按需查询数据的某种方式。

当然,如果无法以合理的金额保持 Spark 数据就绪(但不可查询(“可查询”?我不知道)),这可能不是一个选择。注入小块数据也可能非常耗时,但这对于生产就绪系统来说似乎不太可能。


如果您确实需要将数据分块到每日转储中,您可以使用分段上传。作为比较,我们每分钟从 Firehose 处理几个文件(每天很多 GB),没有明显的开销。

于 2016-09-21T08:32:30.897 回答