我有一个 lambda 函数,它在生产中很少被调用,但它是面向公众的,所以我想避免冷启动。所以我想我可以使用预配置的并发来避免这个问题。我的 Cloudformation 模板如下所示:
QuoteLinkServiceFunction:
Type: AWS::Serverless::Function
Properties:
# other lambda properties...
ProvisionedConcurrencyConfig:
ProvisionedConcurrentExecutions: 1
Run Code Online (Sandbox Code Playgroud)
当我在我的测试环境中创建这个堆栈时(我是唯一的用户,所以没有其他调用同时发生),当我在几个小时后返回使用这个函数时仍然会遇到冷启动。由于 lambda 现在已预热,因此在第一次调用之后立即进行的后续调用会运行得更快。
lambda 控制台显示此函数的别名实际上已设置为预配并发为 1,并且我已验证 ALB 目标组指向别名。那么为什么我仍然冷启动?
Mar*_*Roy 18
长话短说:
我们遇到了同样的问题,但尚未找到任何解决方法。最后,Lambda 实例是暂时的,因此无法保证连续正常运行时间(即使具有预配置的并发性)。
预置并发确实为您提供了许多正在运行的实例的保证 - 尽管这些实例可以在任何时间点与其他实例交换(并且在发生这种情况时会导致冷启动)。交换的频率似乎相当随意,我认为完全取决于 AWS。
编辑:我们最终意识到这根本不是问题!它只与预配置并发功能的本质有关:
通过预配置并发,初始化/冷启动仍然会发生,但它们发生在Lambda 可供调用之前。
然而,如果 lambda 函数没有很好地利用静态初始化,客户端仍然可能会遇到另一种形式的冷启动——静态初始化通常比 Lambda 初始化本身慢:
在我们对跨生产调用的 Lambda 性能的分析中,数据显示函数执行前延迟的最大贡献者来自 INIT 代码。
下面的图片(来自Lambda 性能优化指南)很好地总结了所有这些。
判断 Lambda 是否确实进行冷启动的一个好方法是查看 CloudWatch 中的日志。每个请求都应该有一个REPORT如下所示的日志:
REPORT RequestId: f840a316-cf35-42ec-8f4d-c03a6cde9192 Duration: 368.80 ms Billed Duration: 369 ms Memory Size: 128 MB Max Memory Used: 93 MB Init Duration: 3569.10 ms
Run Code Online (Sandbox Code Playgroud)
如果你看到Init Duration日志末尾,那么确实是冷启动。然而,对于预配置的并发性,此初始化持续时间发生在调用 Lambda之前。
此外,每次 AWS 启动新的 Lambda“实例”时,似乎都会创建一个新的 CloudWatch 日志流 - 这会导致冷启动,每个日志流的第一个请求都有一个Init Duration. 因此,只需查看“首次事件时间”列即可显示所有冷启动(可以通过首选项/齿轮图标添加该列)。
这在Lambda 性能优化指南中得到了进一步证实:
初始化代码的运行频率高于调用总数。由于 Lambda 具有高可用性,因此对于每一个预置并发单元,至少在不同的可用区中准备两个执行环境。这是为了确保您的代码在服务中断时可用。随着环境的收获和负载平衡的发生,Lambda 会过度配置环境以确保可用性。您无需为此活动付费。如果您的代码初始值设定项实现了日志记录,则即使未调用主处理程序,您也会在运行此代码时随时看到其他日志文件。
查看日志也是一个好主意START,以确保正在调用预期版本(配置了预配并发的版本):
START RequestId: f840a316-cf35-42ec-8f4d-c03a6cde9192 Version: 15
Run Code Online (Sandbox Code Playgroud)
确保版本不是$LATEST(无法从预配置并发中受益)尤其重要:
函数的每个版本只能有一个预配置的并发配置。这可以直接位于版本本身上,也可以位于指向该版本的别名上。两个别名无法为同一版本分配预配置并发。此外,您无法在指向未发布版本 ($LATEST) 的别名上分配预配置并发。
| 归档时间: |
|
| 查看次数: |
1684 次 |
| 最近记录: |