0

在我们的堆栈中,我们使用了许多分离的 lambda 函数(每个函数都作为 HTTP 或 WS 处理程序),并且每个函数都导入大小相当大的实用程序。这些必需的实用程序还处理与外部实体(缓存和数据库)的连接,因此每次我们调用该函数时,都会有一个持续 1 到 2 秒的初始化阶段。由于不同的函数有分离的运行时(即使我们使用到同一个数据库的连接并到处缓存),init 阶段发生在每个函数的分离中。如果它们需要相同的依赖关系,这是否可能(可能与 lambda 层)在许多函数之间共享“初始化阶段”?比如基于下面的js代码:

import utils from "../common"

const db = utils.get_db()

export const handler_A = async (event) => {
  // do sth with db here
}

export const handler_B = async (event) => {
  // do sth with db here
}

假设我们的执行顺序如下: handler_A ----> handler_A ----> handler_B

在这种情况下,第二次执行 forhandler_A 应该能够db从第一次执行中重用,但这不适用于handler_b.

这是否可以重用“初始化阶段”,或者换句话说,如果在 handler_B 之前几秒钟使用了 handler_A,则保持 handler_B 的热启动?任何帮助将不胜感激!

4

2 回答 2

1

据我所知,每个 lambda 都在其自己的 firecracker VM 中运行,因此即使代码在同一个 zipfile 中,lambda 执行环境甚至可能不在同一个 VM 上(AWS 会根据工作负载的性质进行一些优化)。所以答案是:不,不可能,因为 AWS 在完全隔离的环境中处理每个 lambda(和 lambda 版本)。

从文档:

使用 Linux 内核中内置的几种类似容器的技术以及 AWS 专有隔离技术将执行环境相互隔离。

他们也有自己的代码副本和自己的/tmp目录,所以没有什么是真正共享的。

https://docs.aws.amazon.com/whitepapers/latest/security-overview-aws-lambda/lambda-isolation-technologies.html

您可以做的最好的事情可能是首先检查为什么设置连接需要这么长时间(2 秒超过平均水平)。有时,简单地将 lambda 大小增加到 >1GB 也会大大减少启动时间,尽管它当然可能不适用于您的情况。

于 2021-09-21T20:43:04.937 回答
1

您将无法共享网络连接,因为离散函数在单独的 firecracker VM 容器中运行,因此这些调用(以及网络连接)可能不在相同的底层主机中。

您在这里有两个选择:

  1. 预置并发。这将使您的功能保持“温暖”,从而避免冷启动期间的连接延迟。
  2. 单 lamdba API 模式。这会将您的函数组合成一个 Lambda 函数,并且您将负责在处理程序代码中进行路由。

mono-lambda API 模式有很多优点和缺点,您可以在此处阅读更多相关信息

于 2021-09-22T15:55:22.633 回答