使用 SQS 触发器的 Lambda 缩放

Lambda scaling with SQS trigger

我已经为我的 Lambda 定义了一个 SQS 触发器。在 Lambda 内部,我正在调用基于令牌(每分钟 250 个令牌)的第 3 方 api。最初我定义了 250 的批量大小,65s 的批量 window,但发生的事情是 lambda 工作 concurrently 来处理请求并且令牌非常耗尽快.

然后在更改批处理大小、window 和并发的各种值后,最终进程开始顺利运行,批处理大小为 10,批处理 window 10 和预留并发数 7 但那次只有队列中有 3,00,000 个产品 ID。昨天,当我将 400 万个产品 ID 推入队列时,令牌再次开始很快耗尽。当我检查日志时,我发现 Lambda 在不同的时间间隔选择不同数量的消息,有时一分钟需要 200 条消息,有时需要 400 条。这个数字每次都不同。

我想要的是无论队列中有多少消息,Lambda 都应该在 1 分钟内从队列中只挑选 250 条消息。如何做到这一点?

我认为 SQS 不是解决此类问题的合适产品。您正在寻找的是 节流,而 SQS 可能不是适合此目的的工具。

例如。您将批量大小设置为 10,将 window 设置为 10。这并不代表您认为的意思。

您要告诉 SQS 在最多 10 秒内批处理最多 10 个项目。但是如果SQS在1秒后有10个项目,它会触发你的Lambda。

从您的要求来看,您向队列中放入的数据似乎多于您可以从中读取的数据。

考虑到这一点,我建议您先将该数据写入 DynamoDB,然后执行一个由 EventBridge 触发的作业,该作业每分钟运行一次,并从 DynamoDB 中准确提取 250 个项目(或您拥有的任何数量的令牌),并且完成工作。

总结:

  1. 将您的项目放入 SQS
  2. 从 SQS 触发 Lambda A
  3. Lambda A 将其写入 DynamoDB
  4. 创建 EventBridge 规则以每 60 秒触发一次 Lambda B
  5. Lambda B 从 DynamoDB 读取 n 项并处理它们

长话短说,您无法完全控制 lambda 如何汇集 SQS。 AWS 代表在 SQS Lambda Trigger Polling Issue :

中明确说明了这一点

Since this is entirely dependent on the Lambda service, the polling mechanism cannot be controlled.

另外,lambda使用five pooling threads:

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

因此,通过您的设置,您可以轻松地在一分钟内获得如此多的池(取决于功能持续多长时间):

7 concurrency * 10 messages in batch * 5 threads * 6 pools per minute = 2100 per minute

作为 AWS rep writes,解决此问题的唯一方法是 不直接使用 SQS 和 lambda:

The only way to mitigate this is to disable the SQS triggers on the Lambda function.