使用 Lambda 保证在 SQS 队列中处理文件的模式

Pattern to guarantee processing of files in an SQS queue using Lambda

我要对上传到 S3 存储桶的许多文件执行一个非常简单的任务。该任务可以通过一个简单的 Lambda 函数轻松执行,并将生成的文件写回 S3。

将此 Lambda 函数连接到由 S3 事件触发的事件是微不足道的,但我有一些额外的复杂性:

  1. 必须处理文件(如果 Lambda 函数失败,则需要再次尝试该操作,直到成功为止,给定合理的重试次数)

  2. 我需要知道所有文件何时处理完毕

在我看来,在系统 (SQS) 中放置一个消息队列似乎是一个明智的选择。这样,任何失败的消息都将在可见性超时后重试。此外,我将能够查询队列长度以查看是否仍有操作正在进行中。

我可以将 S3 事件连接到 SQS 队列。 问题是我无法直接从 SQS 队列触发 Lambda 调用。

File --> S3 --> SQS --??--> Lambda ----> S3
                                    \
                                     `-> If successful delete message from SQS

我可以使用 Kinesis 从队列中获取消息并触发 lambda 函数,但这似乎有点矫枉过正?同样,我可以有专门的实例轮询队列并对其进行操作,但对于这样一个简单的功能,我真的不想 运行 一个实例集群。

有好的设计模式吗?

对于直接从 S3 到 Lambda,我认为您是对的,您需要担心 lambda 函数无法正常工作/崩溃以及未发生对特定 S3 对象的处理。

也就是说,我建议将 S3 直接与 Lambda 结合使用一种机制,该机制允许您检测并重新请求处理未能处理的项目(即保姆)。您可以通过 Lambda (http://docs.aws.amazon.com/lambda/latest/dg/with-scheduled-events.html) 定期安排一个作业来查找未处理的旧项目(早于特定阈值)。大多数处理将在直接(快乐)路径上完成。

实现此目的的一种方法是使用具有延迟交付和 lambda 计划函数的 SQS。 所以你会有

File --> S3 --> Lambda --> S3 (happy path)
             \-> SQS (delayed)
                  \-> Lambda(scheduled job) -> S3 (unhappy path)

在计划的作业中,您可以检查是否进行了处理并确认消息。计划的作业可以触发用于正常处理的相同 Lambda 作业。 另外,不要忘记为 SQS 队列配置一个死信队列,以捕获在多次重试后处理失败的事情。

请记住,如果您有办法通过检查 S3 存储桶来确定已处理的内容和未处理的内容,则您可能会完全绕过 SQS。

另外请记住,以上所有假设都假设您处理已经处理的内容(即涉及 lamda 函数超时、队列延迟和 sqs 传递的边缘情况)