使用AWS Lambda

时间:2016-09-21 08:01:39

标签: amazon-s3 aws-lambda concatenation aws-sdk amazon-kinesis-firehose

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

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

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

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

目前我的数据量很少,每天只有几百MB,但这个数量将来会成倍增长。对我来说奇怪的是,Lambda具有如此低的限制,并且已经使用如此小的文件来访问它们。

或者连接S3数据的替代方案是什么,理想情况下是由S3对象创建的事件或某种预定作业调用,例如每天安排一次?

2 个答案:

答案 0 :(得分:4)

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

  • S3费用会上涨。
  • 管道复杂性将会上升。
  • 从Firehose输入到Spark输入的延迟会增加。
  • 如果单个文件注入Spark失败(this will happen in a distributed system)你必须在一个巨大的文件周围移动,如果注入不是原子的话可能会切片,再次上传,所有这些都需要很长时间才能完成数据。此时您可能会发现恢复的时间太长,以至于您不得不推迟下一次注射......

相反,除非在这种情况下不可能,否则如果你将Firehose文件尽可能地设为 small 并立即将它们发送到Spark

  • 您几乎可以立即归档S3对象,从而降低成本。
  • 尽快在Spark中提供数据。
  • 如果单个文件注入Spark失败,那么数据就会减少,如果你有自动恢复功能,除非某些系统始终处于完全倾斜状态,否则这一点甚至不会引人注意(此时批量注入将是均匀的差)。
  • 建立TCP连接和身份验证会增加一点延迟。

我并不熟悉Spark,但总的来说这样的“管道”解决方案会涉及:

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

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

如果确实需要将数据分块到每日转储中,您可以使用multipart uploads。作为比较,我们正在对Firehose进行每分钟几次文件(每天数GB)的轻量处理,没有明显的开销。

答案 1 :(得分:3)

您可以创建一个Lambda函数,每天只使用Scheduled Events调用一次,在Lambda函数中,您应该使用不需要在Lambda函数上下载文件的Upload Part - Copy。这个thread

中已经有一个例子