AWS - 想要将多个文件上传到 S3,并且仅当所有文件都上传时才会触发 lambda 函数

AWS - want to upload multiple files to S3 and only when all are uploaded trigger a lambda function

我正在就什么是最佳设计方式寻求建议 -

用例

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

天真的方法

我处理这个问题的方法是在 Dynamo 中保存一条记录,其中包含唯一标识符和我将上传的记录总数以及应该存在于 S3 中的密钥。

一个基本的实现是采用我现有的 lambda 函数,该函数在我的 S3 存储桶被写入时调用,并让它手动检查是否所有其他文件都已保存。

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

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

想法

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

更好的方法是什么?我正在考虑使用 SWF 之类的方法,但不确定这对我的解决方案是否过大,或者它是否会让我做我想做的事。该文档也没有显示真实的 "examples" 。这只是一个讨论,没有太多的分步指南(也许我找错地方了)。

编辑 回应 mbaird 下面的建议-

选项 1 (SNS) 这就是我要采用的方法。这很简单,并没有真正违反单一职责原则。也就是说,客户端上传文件并发送通知(通过 SNS)它的工作已完成。

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

无论如何,我都在使用 AWS 技术并与他们的产品(Lambda 函数、SNS 等)耦合,但我觉得依赖 Dynamo 流之类的东西会使它的耦合更加紧密。对于我的用例来说并不是一个大问题,但仍然感觉很脏;D

带有 S3 触发器的选项 3 我担心的是竞争条件的可能性。例如,如果客户端同时上传多个文件(想象一次以不同的文件大小触发多个异步上传),如果两个文件恰好同时完成上传,并且两个或多个 Lambda 函数(或者我们使用的任何实现)查询 Dynamo 并返回 N 作为完成的上传(而不是 N 和 N+1)?现在虽然最后的结果应该是N+2,但是每一个都会给N加1。Nooooooooooo!

因此选项 1 获胜。

如果你不想让客户端程序负责直接调用Lambda函数,那么它做一些更通用的事情就可以了吗?

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

选项 2:(DynamoDB 流) 如果它只是用属性 record.allFilesUploaded = true 之类的东西更新 DynamoDB 记录会怎么样?您可以拥有 Lambda 函数 trigger off the DynamoDB stream。由于您已经通过客户端创建了 DynamoDB 记录,这似乎是一种将这批上传标记为已完成的非常简单的方法,而无需编写代码了解接下来需要发生什么。然后,Lambda 函数可以检查 "allFilesUploaded" 属性,而不必在每次调用时都去 S3 查找文件列表。

或者,在所有文件都完成上传之前不要插入 DynamoDB 记录,这样您的 Lambda 函数可能会触发正在创建的新记录。

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

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