我可以限制 AWS Lambda 的并发调用吗?

Posted

技术标签:

【中文标题】我可以限制 AWS Lambda 的并发调用吗?【英文标题】:Can I limit concurrent invocations of an AWS Lambda? 【发布时间】:2017-06-21 02:23:03 【问题描述】:

我有一个由 PUT 触发到 S3 存储桶的 Lambda 函数。

我想限制这个 Lambda 函数,使其一次只运行一个实例——我不希望两个实例同时运行。

我查看了 Lambda 配置和文档,但看不到任何明显的东西。我可以编写自己的锁定系统,但如果这已经是一个已解决的问题,那就太好了。

如何限制 Lambda 的并发调用次数?

【问题讨论】:

对您为什么关心并发运行的调用数量感兴趣。 @jarmod 当时我正在考虑在 Lambdas 中运行 Terraform 更改,但我不知道如何在 Terraform 本身中进行远程状态锁定。我放弃了这个想法——部分是因为你不能限制并发的 Lambda,部分是因为我担心五分钟的超时。 【参考方案1】:

AWS Lambda 现在支持单个函数的并发限制: https://aws.amazon.com/about-aws/whats-new/2017/11/set-concurrency-limits-on-individual-aws-lambda-functions/

【讨论】:

这太棒了。在 S3 上更新文件时,我能够解决并发问题。我正在使用 lambda 函数使用并发计数为 1 更新 S3 上的文件。这确保了一次只有一个 ec2 实例具有对该文件的写访问权限。这比使用 AWS 上的任何托管数据库进行琐碎使用要便宜得多。 我知道这是 2 岁,但这解决了我遇到的一个问题。谢谢! 这真的是 100% 保存吗?我做了一些研究,如果我得到正确的结果,如果您收到大量消息,您可能会由于节流而导致大量有效消息失败。如这篇详细文章所述:data.solita.fi/…您如何配置您的可见性超时等? @BjörnGrambow 我认为这取决于您如何调用该函数。理想的用例是来自 SQS 的异步调用或事件调用。在此用例中您会遇到的唯一问题是您的事件增长速度是否快于您的处理速度。 这个功能很奇怪。我的用例只是想将特定计划函数的执行限制为不超过一个实例(上限)。但似乎启用并发限制伴随着阻止任何其他 Lambda 使用保留部分的缺点。因此,如果您有 100 个不经常运行但每个并发限制为 10 个的 Lambda,则无论它们是否实际运行,都会占用您账户的所有 Lambda 容量。我可能会做一些其他的事情,比如让额外的执行开始但检查外部锁等。【参考方案2】:

我建议您使用Kinesis Streams(或者DynamoDB + DynamoDB Streams,它们本质上具有相同的行为)。

您可以将 Kinesis Streams 视为 queue。好的部分是您可以将 Kinesis Stream 用作 Lambda 函数的 Trigger。所以任何插入到这个 queue 中的东西都会自动按顺序传递给你的函数。因此,您将能够处理那些 S3 事件,一个接一个地执行 Lambda (一次一个实例)。

为此,您需要创建一个 Lambda 函数,其简单目的是获取 S3 事件 并将它们放入 Kinesis Stream 。然后您将该 Kinesis Stream 配置为您的 Lambda 触发器

当您将 Kinesis Stream 配置为您的 Lambda 触发器 时,我建议您使用以下配置:

批量大小:1 这意味着您的 Lambda 将通过 Kinesis 中的一个事件 被调用。您可以选择更大的数字,您将获得该大小的事件列表(例如,如果您想在一次 Lambda 执行中处理最后 10 个事件,而不是在 10 个连续的 Lambda 执行中处理)。 起始位置:修剪地平线 这意味着它将表现为一个队列 (FIFO)

更多关于AWS May Webinar Series - Streaming Data Processing with Amazon Kinesis and AWS Lambda的信息。

我希望这对遇到类似问题的人有所帮助。

附:请记住,Kinesis Streams 有自己的 pricing。使用 DynamoDB + DynamoDB Streams 可能会更便宜(甚至由于 DynamoDB 的 Free Tier 未过期而免费)。

【讨论】:

这个答案很棒! OP 应该真正接受它作为解决方案。 为确保准确的行为,您还需要一个配置:Kinesis Shard Count: 1 在多分片中 Kinesis Stream 一个 Lambda 在每个流中触发,因此我们可以让多个 Lambda 并行执行。【参考方案3】:

不,这是我非常希望看到 Lambda 支持的事情之一,但目前还没有。问题之一是,如果发生大量 S3 PUT 操作,AWS 将不得不以某种方式将所有 Lambda 调用排队,目前不支持。

如果您在 Lambda 函数中构建了锁定机制,您会如何处理由于锁定而未处理的请求?你会把那些 S3 通知扔掉吗?

大多数人推荐的解决方案是让 S3 将通知发送到 SQS 队列,然后安排您的 Lambda 函数定期运行,例如每分钟一次,并检查队列中是否有需要已处理。

或者,让 S3 将通知发送到 SQS,然后让一个 t2.nano EC2 实例和一个单线程服务轮询队列。

【讨论】:

【参考方案4】:

让 S3“放置事件”导致将消息放置在队列中(而不是涉及 lambda 函数)。该消息应包含对 S3 对象的引用。然后安排一个 lambda 以“短轮询整个队列”。

PS: S3 事件不能触发 Kinesis Stream...只能触发 SQS、SMS、Lambda(请参阅 http://docs.aws.amazon.com/AmazonS3/latest/dev/NotificationHowTo.html#supported-notification-destinations)。 Kinesis Stream 价格昂贵,用于实时事件处理。

【讨论】:

以上是关于我可以限制 AWS Lambda 的并发调用吗?的主要内容,如果未能解决你的问题,请参考以下文章

aws lambda 上的保留并发不会阻止 lambda 进行更多扩展?

AWS lambda 和 Java 并发

C# 使用 AWS lambda 时,我可以确定函数中的析构函数会被执行吗?

AWS批处理 - 如何限制并发作业的数量

如何在AWS Lambda函数中进行外部api调用

如何限制 serverless lambda 函数