一点背景, 我正在使用 Serverless 和 .Net 创建带有 SQS 触发器的 lambda。 事件触发器设置为批量大小为 10k,等待时间(批量窗口即
MaximumBatchingWindowInSeconds
)为 30 秒。
队列的可见性超时设置为近 16 分钟。
现在,我已将 lambda 设置为仅 1 的保留并发度,并运行了一项测试,将 100 个项目发送到队列,并希望只看到一次 lambda 调用恰好包含这 100 个项目。
问题在于,它将队列中的项目分开,并调用 lambda 五次,导致创建了五个包作为 lambda 功能的一部分,而不是我想要的一个包。 (仅供参考,lambda 的输出在消息的 s3 中创建包。我想要更少的大包。)
现在的问题:这是预期的行为吗?如果是这样,为什么当我将队列设置为累积最多 10k 个项目时,结果却是 15 个。
根据 aws 文档,如果有效负载大于 256kb,则 lambda 可以获取比批量大小更少的消息,但我的消息非常小,100 条消息远不及 256kb。所以这不可能是原因。
也欢迎提出处理此问题的替代方案的建议,现在我正在考虑运行一个事件桥调度程序,该调度程序使用 SQS ReceiveMessage api 调用 lambda 并创建一个包,但我还必须确保正确删除队列之后。
我在这里有点无能为力,我很感激你们的任何想法。谢谢。
问题在于,它分离了队列中的项目,并调用了 lambda 五次,导致创建了五个包作为 lambda 功能的一部分,而不是我想要的一个包。
我认为这可能是因为 lambda 使用 五个 SQS 轮询线程来池化 SQS。来自AWS 博客:
Lambda 服务将开始使用 五个并行长轮询连接轮询 SQS 队列。
因此,即使您保留了 1 的并发性,lambda 仍然使用 5 个线程(您无法控制),并且您的 SQS 消息已分发到 到这些线程中。然后,每个线程一一调用您的 lambda 函数,从而观察到 5 次调用。
我认为 FIFO 队列可能是您的解决方案:
“FIFO(先进先出)队列旨在在操作和事件的顺序至关重要或不能容忍重复的情况下增强应用程序之间的消息传递。”
[https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/FIFO-queues.html][1]
MaximumBatchingWindowInSeconds
值。这允许您在调用 lambda 之前收集最多 5 分钟的消息。请记住,SQS 是一种排队机制,而不是批处理机制。批处理是事件源映射的一部分,或者通常可用于 SQS,旨在减少调用次数。它并非旨在提供有保证的批量大小。虽然设置上述值可能会实现您当前的目标,但我不知道您是否可以合理地期望它始终以这种方式工作。另请记住,SQS 是一种“至少一次”交付机制(除非您使用 FIFO,其批量限制为 10)。