AWS Lambda 异步并发限制

Posted

技术标签:

【中文标题】AWS Lambda 异步并发限制【英文标题】:AWS Lambda async concurrency limits 【发布时间】:2018-01-12 18:38:39 【问题描述】:

我正在开发一个 AWS Lambda 函数,该函数目前进行了数百次 API 调用,但在投入生产时它会调用数十万次。问题是我无法以这种规模进行测试。

我正在使用异步模块通过async.eachLimit 执行我的api 调用,以便我可以限制并发(我目前将其设置为300)。

我不明白的是 AWS Lambda 的限制。 the docs 是这样说的:

每次调用的 AWS Lambda 资源限制

文件描述符数:1,024 进程和线程数(合计):1,024

据我了解,Node.js 是单线程的,所以我认为我不会超过这个限制。我没有使用子进程,并且异步库在这方面也不是很好。

现在关于这些文件描述符,我的函数严格调用 AWS 的其余 API,而且我从不写入磁盘,所以 我不认为我正在使用它们。

其他重要的 AWS Lambda 限制是执行时间和消耗的内存。每次执行时都会非常清楚地报告这些内容,并且我完全知道何时接近它们,所以我们现在先忽略这些。

一点上下文:

我的函数的确切性质是,每次体育比赛开始时,我都需要为所有移动设备订阅适当的 SNS 主题,所以基本上我会重复调用我们自己的 mysql 数据库,然后是 AWS SNS 端点。

所以问题是……

在这种情况下,我可以将 AWS Lambda 中的异步并发推送到多远?是否有任何实际限制或其他我没有考虑的可能发挥作用的东西?

【问题讨论】:

你的意思是单次 lambda 执行会进行数十万次调用吗?还是多个 lambda? @LifeQuery 一个 Lambda 执行使用异步在其中进行数千次调用。所以我的后端调用了 Lambda 函数,而 IT 进行了数千次 API 调用。 node.js 实际上不是单线程的。 javascript 在单个线程中执行,但是当您执行 IO(例如网络请求和磁盘操作)时,它实际上会在单独的线程中执行。因此,如果您要使用 async.map 并为每个项目发出网络请求,它可能会创建与您发出的请求一样多的线程。 【参考方案1】:

据我了解,Node.js 是单线程的,所以我认为我不是 会超过这个限制。我没有使用子进程和异步 图书馆在这方面也不是很好。

Node.js 是事件驱动的,不是单线程的。 Javascript 引擎在单个线程(事件循环)上运行,并将 I/O 操作委托给一个内部库 (libuv),该库处理其线程池和异步操作。async 不打开子进程独立,但在幕后,无论您是发出 HTTP 请求还是与文件系统交互,您都将这些操作委托给 libuv

换句话说,您已经在资源限制的情况下很好地回答了您自己的问题:

在这种情况下,我可以将 AWS Lambda 中的异步并发推送到多远?是否有任何实际限制或其他我没有考虑的可能发挥作用的东西?

每次调用的 AWS Lambda 资源限制

文件描述符数:1,024 进程和线程数(合计):1,024

很难说libuv 是否会为每个 I/O 操作打开一个新线程,所以你可能会得到比上面列出的数字多一点的结果。但无论如何,您可能会在达到这些限制之前耗尽或记忆。 底线是不,您将无法在一次 lambda 执行中进行数十万次调用。

关于函数的上下文,根据您的作业需要运行的频率,您可能希望将 lambda 重构为多次执行(它也会运行得更快),或者将它放在 EC2 上并由 lambda 触发自动缩放.

【讨论】:

我相信这些限制适用于相同 lambda 函数的执行。因此,如果您有两个并行执行的函数,那么它们的总数仍然为 1,024。我也将其解释为每次执行,但经过大量测试后,行为与共享限制的所有相同类型的 lambdas 一致。

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

如何绕过 AWS Lambda 大小限制

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

将 aws 资源限制为特定的 ecs 集群

使用 rds-data 增加来自 execute_sql 的 aws lambda 结果计数的 1000 限制或使用不同的包?

如何限制 serverless lambda 函数

AWS Athena 并发限制:提交的查询数 VS 正在运行的查询数