微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

使用 SQS 触发器进行 Lambda 缩放

如何解决使用 SQS 触发器进行 Lambda 缩放

我已经为我的 Lambda 定义了一个 SQS 触发器。在 Lambda 内部,我正在调用基于令牌(每分钟 250 个令牌)的第三方 api。最初我定义了 250 的批处理大小,65s 的批处理窗口,但结果是 lambda 工作 concurrently 来处理请求并且令牌很快耗尽。>

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

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

enter image description here

解决方法

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

例如。您将批量大小设置为 10,将窗口设置为 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 中明确说明了这一点:

由于这完全依赖于 Lambda 服务,因此轮询机制无法控制

此外,lambda 使用 five pooling threads

Lambda 服务将开始使用五个并行长轮询连接轮询 SQS 队列。

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

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

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

缓解这种情况的唯一方法是禁用 Lambda 函数上的 SQS 触发器

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。