AWS - 希望将多个文件上传到S3,并且仅在上传所有文件时触发lambda函数

时间:2015-12-20 00:02:54

标签: amazon-web-services amazon-s3 aws-lambda amazon-swf

我正在寻求建议的最佳方法 -

使用案例

我想将多个文件放入S3。一旦所有文件都成功保存,我想触发一个lambda函数来完成其他工作。

天真的方法

我接近这一点的方法是在Dynamo中保存一条记录,其中包含一个唯一标识符以及我将上传的记录总数以及S3中应存在的密钥。

基本的实现是获取我现有的lambda函数,该函数在我的S3存储桶被写入时随时调用,并且手动检查是否已保存所有其他文件。

Lambda函数会知道(查看Dynamo以确定我们要查找的内容)并查询S3以查看其他文件是否在其中。如果是,请使用SNS触发另一个将执行其他操作的lambda工作

编辑:另一种方法是让我的客户端程序将S3中的文件放在直接调用其他lambda函数的位置,因为从技术上讲,它知道所有文件的上传时间。这种方法的问题是我不希望这是客户端程序的责任......我希望客户端程序不在乎。一旦上传了文件,它就应该能够退出。

思想

我不认为这是个好主意。主要是因为Lambda函数应该是轻量级的,并且从Lambda函数中轮询数据库以获取所有上载文件的S3密钥,然后在S3中检查它们是否存在 - 每次执行此操作似乎都是贫民窟并且非常重复。

更好的方法是什么?我在考虑使用SWF,但我不确定这对我的解决方案是否过度,或者它是否会让我做我想做的事情。文档没有显示真实的"示例"无论是。这只是一个没有太多分步指导的讨论(也许我正在寻找错误的位置)。

修改以回应mbaird的建议 -

选项1(SNS)这就是我要使用的内容。它很简单,并没有真正违反单一责任委托人。也就是说,客户端上传文件并发送通知(通过SNS)其工作已完成。

选项2(Dynamo流)所以这实际上是另一个"实现"选项1的客户端进行服务调用,在这种情况下,会导致表更新与SNS通知(选项1)。此更新将触发Lambda函数,而不是通知。这不是一个糟糕的解决方案,但我更喜欢使用SNS进行通信,而不是依靠数据库的功能(在本例中为Dynamo流)来调用Lambda函数。

在任何情况下,我都使用AWS技术并与其产品(Lambda函数,SNS等)结合使用,但我觉得依靠Dynamo流之类的东西使它更加紧密耦合。对我的用例来说并不是一个大问题,但仍然感觉很脏; D

带有S3触发器的选项3 我关注的是竞争条件的可能性。例如,如果客户端同时上传多个文件(考虑使用不同的文件大小立即触发多个异步上传),如果两个文件几乎同时完成上传,以及两个或更多Lambda函数,那该怎么办?或者我们使用的任何实现)查询Dynamo并获取N作为完成的上传(而不是N和N + 1)?现在即使最终结果应为N + 2,每个人也会加1到N. Nooooooooooo!

所以选项1获胜。

1 个答案:

答案 0 :(得分:3)

如果您不希望客户端程序直接负责调用Lambda函数,那么它是否可以执行更通用的操作?

选项1:(SNS)如果它只是通知SNS主题它已完成一批S3上传,该怎么办?您可以将Lambda函数订阅到该SNS主题。

选项2 :( DynamoDB Streams)如果只是使用属性record.allFilesUploaded = true更新了DynamoDB记录,该怎么办?您可以使用Lambda函数trigger off the DynamoDB stream。由于您已经通过客户端创建了DynamoDB记录,这似乎是一种非常简单的方法,可以将上传批次标记为完整,而无需编写有关下一步需要发生的事情的代码。 Lambda函数然后可以检查" allFilesUploaded"每次调用时都不需要转到S3获取文件列表。

或者,不要插入DynamoDB记录,直到所有文件都完成上传,然后您的Lambda函数才能触发正在创建的新记录。

选项3 :(继续使用S3触发器)如果客户端程序无法从今天的工作方式进行更改,那么请不要列出所有S3文件并将它们与每次出现新文件时,都会在DynamoDB中列出,只需通过atomic counter更新DynamoDB记录。然后将结果值与文件列表的大小进行比较。一旦值相同,您就知道所有文件都已上传。不利的一面是,您需要在DynamoDB表上配置足够的容量来处理所有更新,这将增加您的成本。

另外,我同意你的看法,SWF对这项任务来说太过分了。