具有 SQSEvent 和大批量大小的 Lambda 调用多个实例,每个实例处理几个项目

Lambda with SQSEvent & large batch size invokes multiple instances each handling few items

一点背景, 我正在使用无服务器和 .Net 创建带有 SQS 触发器的 lambda。 事件触发器设置为 10k 的批处理大小和 30 秒的等待时间(批处理 Window 即 MaximumBatchingWindowInSeconds)。 队列的可见性超时设置为将近 16 分钟。

现在我已经将 lambda 设置为只有 1 个保留并发,运行 一个测试,我将 100 个项目发送到队列并且希望只看到一个 lambda 调用恰好包含这 100 个项目。

问题是它将队列中的项目分开并调用了 lambda 五次,导致创建了五个包作为 lambda 功能的一部分,而不是我想要的一个包。 (仅供参考,lambda 的输出在消息的 s3 中创建了包。我想要更少的大包。)

现在问题:这是预期的行为吗?如果是这样,当我将队列设置为最多累积 10k 个项目时,为什么会这样,而不是 15 个。

根据 aws docs 如果有效负载大于 256kb,lambda 可以抓取比 batchSize 更少的消息,但我的消息非常小,100 条消息不接近 256kb。所以这不是原因。

也欢迎提出解决此问题的替代方案的建议,现在我正在考虑 运行 一个事件桥调度程序,它使用 SQS ReceiveMessage api 调用 lambda 并创建一个包但是然后我还必须确保之后正确删除队列。

我在这里有点无能为力,我很感激你们的任何想法。谢谢

我认为 FIFO 队列可能是您的解决方案:

“FIFO(先进先出)队列旨在在操作和事件的顺序至关重要时或不能容忍重复的情况下增强应用程序之间的消息传递."

[https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/FIFO-queues.html][1]

您可以尝试在事件源映射上设置 MaximumBatchingWindowInSeconds 值。这允许您在调用 lambda 之前收集最多 5 分钟的消息。

请记住,SQS 是一种排队机制,而不是批处理机制。批处理是事件源映射的一部分,或者通常可用于 SQS,旨在减少调用次数。它并非旨在提供有保证的批量大小。虽然设置上述值可能会实现您当前的目标,但我不知道您是否可以合理地期望它始终以这种方式工作。还要记住,SQS 是一种“至少一次”的交付机制(除非您使用 FIFO,它的批次限制为 10)。

Problem was that it separated the items in the queue and invoked the lambda five times instead, causing five packages to be created as part of the lambda's functionality instead of the one package I wanted.

我认为这可能是因为 lambda 使用 5 个 SQS 池化线程 来池化 SQS。来自 AWS blog:

Lambda service will begin polling the SQS queue using five parallel long-polling connections.

因此,即使您保留了 1 的并发性,lambda 仍然使用 5 个线程(您无法控制),并且您的 SQS 消息被分发 到这些线程中。然后,每个线程一个接一个地调用您的 lambda 函数,导致观察到 5 次调用。