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

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

我正在寻求有关设计此最佳方式的建议-

用例

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

天真的方法

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

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

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

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

感想

我不认为这是一个好主意。主要是因为 Lambda 函数应该是轻量级的,并且从 Lambda 函数内轮询数据库以获取所有上传文件的 S3 key ,然后检查 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,每个人都会在 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 表上预置足够的容量来处理所有更新,这会增加您的成本。

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

关于amazon-web-services - AWS - 想要将多个文件上传到 S3,并且只有当所有文件都上传时才会触发 lambda 函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34376697/

相关文章:

javascript - 将 JSON 文件从 S3 存储桶加载到 React 组件

php - WooCommerce Retina图像支持-不包含在srcset中

amazon-web-services - 将端口添加到现有的kubernetes服务

node.js - 获取位于特定 S3 文件夹下的对象列表

node.js - 使用 EBS 和 ELB 环境在 node.js Express 应用程序中将 http 转发到 https

amazon-web-services - AWS CLI 未知组件 : credential_provider

amazon-web-services - 是否可以使用 AWS API 为 Lambda 函数设置 AWS API Gateway 端点?

bash - 从节点 AWS Lambda 函数运行 bash 脚本

amazon-web-services - 一次仅执行一项 Glue 作业/顺序执行 Glue 作业

amazon-web-services - 如何通过主 ID 以外的列从 DynamoDB 检索数据