如何限制无服务器Lambda函数的并行执行

8

我正在使用AWS和Serverless框架。我的Serverless Lambda函数通过事件被触发。然后我与数据库通信,但是我可以打开的连接数量有限。

因此,我想一次只运行5个Lambda函数并排队其他事件。我知道这里有:

    provisionedConcurrency: 3 # optional, Count of provisioned lambda instances
    reservedConcurrency: 5 # optional, reserved concurrency limit for this function. By default, AWS uses account concurrency limit

在这种情况下,指定数量的长时间运行的作业将存在,并且它们将为事件提供服务。

但是我想要的是事件排队,并且函数将被触发,以便最多同时运行5个函数。

我想知道AWS是否支持这种事件排队的概念?


你可以使用 SQS。 - jellycsc
我认为SQS不是解决这个问题的方案。在这里,我正在尝试限制Lambda函数的并行执行数量。 - Exploring
你的 Lambda 函数由哪些事件触发? - tsamaya
2个回答

15

AWS Lambda 中的并发限制决定了一个区域内可以同时运行多少函数调用。您可以通过 AWS Lambda 控制台或 Serverless Framework 设置此限制。

AWS Lambda Concurrency

如果您的账户限制为1000,您为一个特定函数保留了100个并发执行和另一个100个并发执行,则该地区中其余的函数将共享剩余的800个执行。如果您为特定函数预留并发执行,则AWS Lambda会假定您知道要预留多少以避免性能问题。具有分配并发性的函数无法访问未预留的并发性。在Serverless Framework中设置保留并发限制的正确方法是您分享的方法。
functions:
  hello:
    handler: handler.hello # required, handler set in AWS Lambda
    reservedConcurrency: 5 # optional, reserved concurrency limit for this function. By default, AWS uses account concurrency limit

我建议使用SQS来管理您的队列。使用队列的常见架构原因之一是限制对架构的其他部分的压力。这可能意味着在处理大批量消息时,防止数据库过载或避免第三方API的速率限制。
例如,让我们考虑您的情况,其中您的SQS处理逻辑需要连接到数据库。您希望将工作程序限制为每次最多只有5个打开的数据库连接,并通过并发控制设置适当的限制以保持架构稳定。
在您的情况下,您可以拥有一个名为hello的函数,该函数接收您的请求并将它们放入SQS队列中。另一方面,函数compute将获取这些SQS消息并计算它们,限制并发调用的数量为5。
您甚至可以设置批处理大小,即可以包含在单个lambda中的SQS消息数量。
functions:
  hello:
    handler: handler.hello

  compute:
    handler: handler.compute
    reservedConcurrency: 5
    events:
      - sqs:
          arn: arn:aws:sqs:region:XXXXXX:myQueue
          batchSize: 10 # how many SQS messages can be included in a single Lambda invocation
          maximumBatchingWindow: 60 # maximum amount of time in seconds to gather records before invoking the function

这是理论,但似乎并不总是按预期工作,正如在各种帖子中报告的那样,例如 https://zaccharles.medium.com/lambda-concurrency-limits-and-sqs-triggers-dont-mix-well-sometimes-eb23d90122e0 或 https://www.foxy.io/blog/we-love-aws-lambda-but-its-concurrency-handling-with-sqs-is-silly/。 - Mauro Mascia

0
你有没有考虑过使用代理端点(就像一个池子一样)来替代限制 lambda 的并发数。另外,我认为 lambda 和 SQS 之间的通信是通过某个事件池发生的,如果将并发设置得比正在进行的线程数量低,那么你就必须处理丢失的消息。

https://aws.amazon.com/rds/proxy/


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接