了解 亚马逊云科技 Lambda 的调用限制限制

作者: 詹姆斯·贝斯威克 | 202

这篇文章由 亚马逊云科技 Lambda 首席工程师 Archana Srikanta 撰写。

当您调用 亚马逊云科技 L ambda 的调用 API 时,系统会评估一系列限制以确定您的调用是允许还是通过 429 个 “请求过多” 异常。这篇博客文章解释了最常见的调用限制及其之间的关系,因此您可以更好地了解在 Lambda 上扩展工作负载。

概述

Invoke call flow

限制的存在是为了保护 Lambda 内部服务架构的以下组件以及您的工作负载免受嘈杂邻居的影响:

  • 执行环境: 执行环境是运行函数代码的 Firecracker microVM 。给定的执行环境一次只能托管一次调用,但可以重复用于相同函数版本的后续调用。
  • 调用数据平面: 这些是一系列内部 Web 服务,它们在调用时选择(或创建)沙箱并将您的请求路由到该沙箱。这也负责强制执行油门限制。

当您进行 Invoke API 调用时,它会通过部分或全部 Invoke Data Plane 服务进行传输,然后到达下载和执行函数代码的执行环境。

有三个不同但相关的限制共同决定了您的调用请求是被数据层面接受还是受到限制。

并发性

并发 意味着 “存在、正在发生或同时完成”。因此,Lambda 并发限制是对在任何给定时间允许同时进行飞行中调用的限制。它本身不是速率或每秒事务数 (TPS) 限制,而是对可以同时进行多少次调用的限制。 本文档 直观地解释了并发的概念。

在幕后,并发限制大致相当于对您的账户在任何给定时间点可以申领的最大执行环境(以及Firecracker MicroVMS)数量的限制。Lambda 运行着一组多租户裸机实例,Firecracker microVMS 是在这些实例上设计的,可用作您的函数的执行环境。亚马逊云科技 会根据传入的需求持续监控和扩展该机队,并在客户之间公平共享可用容量。

并发限制有助于保护 Lambda 免受单个客户耗尽所有可用容量并导致其他客户拒绝服务的影响。

每秒交易量 (TPS)

客户经常询问他们的并发限制如何转换为 TPS。答案取决于你的函数调用持续多长时间。

Relation between concurrency and TPS

上图考虑了三种情况,每种情况的函数调用持续时间不同,但固定并发限制为 1000。在第一种情况下,调用的持续时间为 1 秒。这意味着您可以启动 1000 次调用,并声明您的并发限制允许的所有 1000 个执行环境。这些执行环境整整一秒钟都处于繁忙状态,并且您无法在那一秒钟内开始任何调用,因为您的并发限制使您无法请求更多的执行环境。因此,在并发限制为 1000、函数持续时间为 1 秒的情况下可以实现的 TPS 为 1000 TPS。

在案例 2 中,调用持续时间减半至 500 毫秒,相同的并发限制为 1000。您可以像以前一样在第二秒开始时启动 1000 次并发调用。这些调用使执行环境在下半段处于繁忙状态。完成后,您可以在相同的执行环境中再启动 1000 次调用,同时仍处于并发限制之内。因此,通过将功能持续时间减半,你的 TPS 翻了一番,达到 2000。

同样,在案例 3 中,如果你的函数持续时间为 100 毫秒,你可以在一秒钟内启动 10 轮,每轮 1000 次调用,从而达到 10K 的 TPS。

将其编码为方程式,在给定并发限制的情况下可以实现的 TPS 为:

TPS = 并发性/函数持续时间(以秒为单位)

极端地说,在函数持续时间仅为 1 毫秒且并发限制为 1000(默认限制)的情况下,一个账户可以带来一百万的调用 TPS。通过提高限额每增加一个额外的并发单位,每增加一个单位的并发量,它就会隐含地额外增加 1000 TPS。高 TPS 不需要任何额外的执行环境(Firecracker microVMS),因此从机队容量的角度来看,这没有问题。但是,从单个账户获得超过一百万的 TPS 会给 Invoke Data Plane 服务带来压力。还必须保护它们免受邻居的噪音冲击,这样所有客户都能公平分享服务的带宽。光靠并发限制不足以防范这种情况——TPS 限制提供了这种保护。

在撰写本文时,调用 TPS 的上限为并发的 10 倍。添加到前面的方程式中:

TPS = 最小值(10 x 并发性、并发性/函数持续时间,以秒为单位)

在 min 函数中,并发因子在两个术语中都很常见,因此关键比较是:

分钟(10,1 /函数持续时间,以秒为单位)

如果函数持续时间正好是 100 毫秒(或 1/10 秒),则最小函数中的两个项是相等的。如果函数持续时间超过 100 毫秒,则第二项较短,并且 TPS 受到并发/功能持续时间的限制。如果函数持续时间低于 100 毫秒,则第一项会更短,并且每 10 倍并发时长 TPS 会受到限制。

Limits for functions less than 100ms

总而言之,TPS 限制的存在是为了保护 Invoke Data Plane 免受短暂调用的高流失的影响,而仅凭并发限制就能提供过高的 TPS。如果您进行低于 100 毫秒的短调用,则吞吐量上限将如上图所示,函数持续时间为 100 毫秒(10 倍并发时)。这意味着短期调用可能受到 TPS 限制,而不是并发限制。但是,如果您的函数持续时间超过 100 毫秒,则可以有效地忽略 10 倍并发 TPS 限制,将可用的 TPS 计算为并发/函数时长。

爆裂

第三个油门限制是爆发限制。Lambda 不会始终为您的整个并发限制预置执行环境。这将是浪费的,尤其是在使用高峰是短暂性的情况下,就像许多工作负载一样。取而代之的是,如果不存在执行环境,则该服务会在调用到来时及时启动执行环境。执行环境启动后,它将在一段时间内保持 “温暖” 状态,并可用于托管相同函数版本的后续调用。

但是,如果调用找不到温暖的执行环境,则在我们预置新的执行环境时,它会出现 “冷启动”。冷启动涉及热调用路径之外的某些额外操作,例如下载代码或容器以及在执行环境中初始化应用程序。这些初始化操作的计算量通常很大,因此与温调用路径相比,吞吐量较低。如果冷启动次数突然急剧增加,可能会给处理这些冷启动操作的调用服务带来压力,还会给应用程序带来不良的副作用,例如延迟增加、缓存效率降低以及对下游依赖关系的扇出率增加。突发限制的存在是为了防止这种冷启动激增,特别是对于具有高并发限制的账户。它可确保逐步攀升至高并发限制,从而平滑突发冷启动的次数。

用于强制执行突发限制的算法是 令牌桶 速率限制算法。以一个装有代币的桶为例。存储桶的最大容量为 B 代币(突发)。存储桶开始装满。每次发送需要额外并发单位的调用请求时,都会从存储桶中提取一个令牌。如果令牌存在,则会授予您额外的并发权限,并将该令牌从存储桶中移除。存储桶以每分钟 r 个代币(速率)的恒定速率进行充值,直到达到最大容量。

Token bucket

这意味着并发的上升速度仅限于每分钟 r 个代币。尽管该算法允许你收集最多 B 个代币并爆发,但你必须等待桶装满后才能再次爆发,这实际上将平均速率限制为每分钟 r。

Concurrency burst limit chart

上面的图表显示了实际的突发限制,最大并发限制为 3000,最大突发次数 (B) 为 1000,充值速率 (r) 为 500 /分钟。代币桶起初装满 1000 个代币,可用的爆发余量也是如此。

在第一分钟和第二分钟之间有一个突发活动,它消耗了存储桶中的所有代币,并声称突发限制允许的所有 1000 个并发执行环境。此时存储桶为空,尽管尚未达到最大并发性,但任何声称拥有更多并发执行环境的尝试都会受到突发限制。

代币桶和爆发净空在第二分钟和第三分钟补充,每分钟补充 500 个代币,使其恢复到最大容量 1000 个。在第四分钟,由于水桶已达到最大容量,因此无需额外补充。在第 4 分钟到第 5 分钟之间,有第二次突发活动再次清空存储桶,并声称额外拥有 1000 个执行环境,使活跃执行环境的总数达到 2000 个。

在第 5 分钟和第 6 分钟,存储桶继续以每分钟 500 的速度补充。此时,已经积累了足够的代币来满足 3000 的全部并发限制,因此,即使您在第七分钟有第三次爆发活动,存储桶也不会再充值。在第十分钟,当所有使用量下降时,可用的爆发余量会慢慢向后退到最大初始爆发量 1K。

最大突发量和充值速率的实际数字因地区而异,可能会发生变化,请访问 Lambda 突发限额页面 了解具体值。

区分突发限制不是对调用本身的速率限制,而是对并发上升速度的速率限制,这一点很重要。但是,由于调用 TPS 是并发函数,因此它还限制了 TPS 上升的速度(速率限制的速率限制)。下图显示了 TPS 爆发余量如何遵循与并发突发净空相似的阶梯步进模式,但仅使用乘数。

Burst limits chart

结论

这篇博客解释了应用于 Lambda 调用的三个关键限制值:并发限制、TPS 限制和突发限制。它概述了这些限制之间的关系,以及每个限制如何保护系统和您的工作负载免受邻居噪音的影响。有了这些知识,您就可以更好地解释在 Lambda 上扩展应用程序时可能遇到的任何 429 个限制异常。有关 Lambda 入门的更多信息,请访问 开发 者指南。

如需更多无服务器学习资源,请访问 无服务器世界