gpt4 book ai didi

java - 如何提高从 AWS Lambda (Java) 初始调用 AWS 服务的性能?

转载 作者:行者123 更新时间:2023-12-05 09:07:16 24 4
gpt4 key购买 nike

我最近尝试分析 AWS Lambda 中托管的服务的一些性能问题。分解这个问题,我意识到这只是在每个容器的第一次调用中。在隔离问题时,我发现自己创建了一个新的测试项目来获得一个简单的示例。

Test project(您可以克隆它,构建它 mvn package,部署它 sls deploy,然后通过 AWS 管理控制台测试它。)

这个项目有 2 个 AWS Lambda 函数:sourcetargettarget 函数只返回一个空的 json {}source 函数使用 AWS Lambda SDK 调用 target 函数。

target 函数的大约持续时间在冷启动时为 300-350 毫秒,在热调用时为 1 毫秒。source 函数的大约持续时间在冷启动时为 6000-6300 毫秒,在热调用时为 280 毫秒。

source 函数冷启动的 6 秒开销似乎是获取客户端的 3 秒和调用其他函数的 3 秒,在热调用中分别为 3 毫秒和 250 毫秒。对于 AWS SNS 等其他服务,我得到了类似的时间。

我真的不明白它在那 6 秒内做了什么,也不知道我能做些什么来避免它。在进行热身调用时,我可以获得客户端并存储引用以避免前几秒,但其他几秒来自实际使用其他服务(SNS、Lambda 等),我不能真正做到无操作。

那么,其他人是否经历过相同的冷启动持续时间,我可以做些什么来提高性能? (除了设置内存)

最佳答案

Java Lambda 冷启动时间慢的主要原因是需要加载类和初始化对象。对于简单的程序,这可能非常快:除了打印“Hello, World”之外什么都不做的 Lambda 将在大约 40 毫秒内运行,这类似于 Python 运行时。另一方面,Spring 应用程序将花费更多时间来启动,因为即使是一个简单的 Spring 应用程序也会在它执行任何有用的操作之前加载数千个类。

虽然减少冷启动时间的明显方法是减少需要加载的类的数量,但这很少容易做到,而且通常是不可能的。例如,如果您在 Spring 中编写 Web 应用程序,则无法在处理 Web 请求之前初始化 Spring 应用程序上下文。

如果这不是一个选项,并且您正在使用 Maven Shade 插件生成“uber-JAR”,您应该切换到我描述的 Assembly 插件 here .原因是 Lambda 会解压缩您的部署包,因此“uber-JAR”会变成许多必须单独打开的小类文件。

最后,增加内存分配。毫无疑问,这是您可以为 Lambda 性能、Java 或其他方式做的最好的事情。首先,因为增加内存减少了 Java 垃圾收集器必须做的工作量。其次,因为 amount of CPU that your Lambda gets is dependent on the memory allotment .在 1,769 MB 之前,您不会获得完整的虚拟 CPU。我建议为 Java 应用程序分配 2 GB;更大分配的成本通常被减少的 CPU 需求所抵消。

不会做的一件事是为预配置的并发付费。如果你想让机器一直运行,请使用 ECS/EKS/EC2。并认识到,如果您的需求激增,您仍然会冷启动。


更新:我在假期里花了一些时间量化各种性能改进技术。完整的文章是 here ,但这些数字值得重复。

我的示例程序与 OP 一样,是一个“什么都不做”,它只是创建了一个 SDK 客户端并使用它来调用 API:

public void handler(Object ignored, Context context)
{
long start = System.currentTimeMillis();

AWSLogs client = AWSLogsClientBuilder.defaultClient();

long clientCreated = System.currentTimeMillis();

client.describeLogGroups();

long apiInvoked = System.currentTimeMillis();

System.err.format("time to create SDK client = %6d\n", (clientCreated - start));
System.err.format("time to make API call = %6d\n", (apiInvoked - clientCreated));
}

我用不同的内存大小运行它,每次都强制冷启动。所有时间都以毫秒为单位:

|                   |  512 MB | 1024 MB | 2048 MB | 4096 MB |
|+++++++++++++++++++|+++++++++|+++++++++|+++++++++|+++++++++|
| Create client | 5298 | 2493 | 1272 | 1019 |
| Invoke API call | 3844 | 2023 | 1061 | 613 |
| Billed duration | 9213 | 4555 | 2349 | 1648 |

正如我上面所说,增加内存的主要好处是同时增加了 CPU。创建和初始化一个 SDK 客户端是 CPU 密集型的,所以你能给它的 CPU 越多越好。


更新 2:今天早上我尝试使用 GraalVM 编译一个简单的 AWS 程序.构建独立的可执行文件需要几分钟,而且由于 AWS SDK 的依赖性,它甚至创建了一个“后备镜像”(具有嵌入式 JDK)。当我比较运行时时,使用标准 Java 运行时没有区别。

底线:将 Java 用于运行时间足以从 Hotspot 中获益的事物。对于短期运行且需要低延迟的事物,请使用不同的语言(Python、JavaScript,也许是 Go)。

关于java - 如何提高从 AWS Lambda (Java) 初始调用 AWS 服务的性能?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65157346/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com