”工欲善其事,必先利其器。“—孔子《论语.录灵公》
首页 > 编程 > AWS Lambda 与 Java xvs arm 的性能 - 部分初始测量

AWS Lambda 与 Java xvs arm 的性能 - 部分初始测量

发布于2024-08-02
浏览:157

AWS Lambda performance with Java  xvs arm- Part nitial measurements

介绍

到目前为止,我还没有针对 arm64 架构的某些用例(例如发出 DynamoDB 请求)使用 Java 21 运行时测量 Lambda 函数的性能(热启动时间和冷启动时间),因为它不支持 SnapStart。具有 Java 21 运行时(采用 x86_64 架构且启用了 SnapStart)的 Lambda 将优于采用 arm64 架构的 Lambda(通过额外的启动优化更是如此)。但在 2024 年 7 月 18 日,AWS 宣布 AWS Lambda 现在支持使用 ARM64 架构的 Java 函数的 SnapStart。因此,现在开始测量冷启动时间和热启动时间并考虑 Lambda 函数架构的选择对我来说是有意义的。据了解,按照目前AWS Lambda的定价内存设置和执行时长,arm64架构的Lambda将约为。比 x86_64 架构的 Lambda 便宜 25%。

我决定为其创建单独的文章系列,而不是将此主题添加到我不断增长的 AWS Lambda SnapStart 系列中。

测量示例应用的冷启动和热启动

在我们的实验中,我们将重复使用 AWS Lambda SnapStart - 测量 Java 21 Lambda 冷启动一文中介绍的应用程序。这是示例应用程序的代码。基本上有 2 个主要 Lambda 函数,它们都响应 API Gateway 请求以使用给定 id 创建产品(请参阅 PutProductFunction Lambda 函数)并通过给定 id 检索产品(请参阅 GetProductByIdFunction Lambda 函数)。您可以在启用或不启用 SnapStart 的情况下使用 Lambda 函数。我编写了一个额外的 Lambda 函数 GetProductByIdWithPrimingFunction,用于独立测量 DynamoDB 请求启动对启用 SnapStart 的 Lambda 函数的影响。您可以在我的文章 AWS Lambda SnapStart - 测量启动、端到端延迟和部署时间中阅读有关启动效果的更多信息。

要在所有 Lambda 函数上启用 SnapStart,请取消 SAM 模板中以下内容的注释:

Globals:
  Function:
    CodeUri: target/aws-pure-lambda-snap-start-21-1.0.0-SNAPSHOT.jar
    ...
    SnapStart:
     ApplyOn: PublishedVersions  
   ...

如果我只想将 SnapStart 用于单个函数,而不是所有 Lambda 函数,则必须在 Lambda 函数级别而不是全局函数级别应用此 SnapStart 定义。

所有 Lambda 函数都以以下设置为起点:

  • 1024 MB内存设置
  • 用于与 DynamoDB 数据库通信的默认 HTTP Apache 客户端
  • Java 编译选项“-XX: TieredCompilation -XX:TieredStopAtLevel=1”被证明可以在冷启动时间和热启动时间之间提供非常好的权衡

在 SAM 模板中,我添加了在全局 Lambda 函数部分中定义 Lambda 架构的可能性,例如:

Globals:
  Function:
    CodeUri: target/aws-pure-lambda-snap-start-21-1.0.0-SNAPSHOT.jar
    ...
    Architectures:
      #- arm64
      - x86_64   

只需取消注释您想要用于 Lambda 函数的架构。

即使 Java 是“一次编写,到处运行”,我还是通过预先安装在带有 Graviton 处理器(基于 arm64/aarch64 架构)的 t4g AWS EC2 实例上编译并构建了应用程序 jar 文件,用于我的 arm64 测量适用于 Linux aarch64 的 Amazon Corretto 21。你可以在这里找到这个罐子。

我还再次重新测量了 x86_64 架构的所有内容,以便使用相同的 Corretto Java 21 最新运行时版本(在我测量时为 Java 21.v17 )获得可比较的结果。

下面的实验结果基于再现超过 100 次冷启动和大约 100.000 次热启动。为此(以及我上一篇文章中的实验),我使用了负载测试工具嘿,但是您可以使用任何您想要的工具,例如 Serverless-artillery 或 Postman。 同样重要的是要注意,我在应用程序的新源代码(重新)部署之后立即开始测量。请注意,快照分层缓存对冷启动也有影响,第一次调用通常较慢,后续调用会变快,直到达到一定数量的调用。

现在,让我们将“通过现有 id 获取产品”的所有测量结果(Lambda 函数 GetProductByIdFunction 和 GetProductByIdWithPrimingFunction 用于启用 SnapStart 和启动测量)情况放在一起。

冷 (c) 和热 (m) 启动时间(以毫秒为单位):

方法 c p50 c p75 c p90 c p99 c p99.9 c 最大 w p50 w p75 w p90 w p99 w p99.9 w 最大值
x86_64,未启用 SnapStart 3554.30 3615.21 3666.15 3800.47 4108.61 4111.78 5.42 6.01 6.88 14.09 40.98 1654.59
arm64,未启用 SnapStart 3834.81 3904.42 3983.26 4047.47 4332.13 4335.74 5.96 6.66 7.69 16.01 43.68 1844.54
x86_64,无需启动即可启用 SnapStart 1794.09 1846.86 2090.54 2204.27 2239.80 2240.08 5.37 5.96 6.93 15.88 51.64 1578.34
arm64,无需启动即可启用 SnapStart 1845.01 1953.18 2591.70 2762.91 2793.45 2795.8 5.91 6.56 7.63 16.75 63.52 1779.14
x86_64,通过 DynamoDB 请求启动启用 SnapStart 803.18 870.18 1103.78 1258.19 1439.95 1440.67 5.55 6.25 7.45 15.50 63.52 448.85
arm64,通过 DynamoDB 请求启动启用 SnapStart 910.14 1001.79 1376.62 1623.44 1684.60 1686.19 6.05 6.72 7.81 16.66 74.68 550.59

结论

在本文中,我们针对 3 个用例比较了连接 DynamoDB 数据库的 Lambda 函数的冷启动时间和热启动时间的测量结果:

  • 未在 Lambda 函数上启用 SnapStart
  • 在 Lambda 函数上启用 SnapStart,但没有启动优化
  • 在 Lambda 函数上启用 SnapStart 并启动 DynamoDB 请求

我们发现,通过使用 x86_64 架构,所有冷启动和热启动时间都比arm64 架构要短。但由于 arm64 架构 Lambda 定价比 x86_64 架构便宜 25%,它引入了非常有趣的性价比权衡。

对于我们的测量,对于所有 3 个用例:

  • 与 x86_64 架构相比,arm64 架构的 Lambda 冷启动时间在许多百分位上仅慢 10-20%(仅在极少数情况下慢 25-27%)。
  • arm64 架构的 Lambda 热启动时间在许多百分位数上仅比 x86_64 架构慢 5-10%。

因此,对于这个示例应用程序来说,选择arm64架构是相当合理的。由于 SnapStart 对 arm64 架构的支持最近才推出,我也预计未来会有一些性能改进。请根据您的用例自行测量!

在本文的下一部分中,我们将进行相同的性能测量,但将 Lambda 内存设置为 256 到 2048 MB 之间的不同值,并比较结果。

版本声明 本文转载于:https://dev.to/aws-builders/aws-lambda-performance-with-java-21-x86-vs-arm64-part-1-initial-measurements-506?1如有侵犯,请联系[email protected]删除
最新教程 更多>
  • HTML 格式标签
    HTML 格式标签
    HTML 格式化元素 **HTML Formatting is a process of formatting text for better look and feel. HTML provides us ability to format text without us...
    编程 发布于2024-12-28
  • 如何在 PHP 中组合两个关联数组,同时保留唯一 ID 并处理重复名称?
    如何在 PHP 中组合两个关联数组,同时保留唯一 ID 并处理重复名称?
    在 PHP 中组合关联数组在 PHP 中,将两个关联数组组合成一个数组是一项常见任务。考虑以下请求:问题描述:提供的代码定义了两个关联数组,$array1 和 $array2。目标是创建一个新数组 $array3,它合并两个数组中的所有键值对。 此外,提供的数组具有唯一的 ID,而名称可能重合。要求...
    编程 发布于2024-12-28
  • 如何使用 MySQL 查找今天生日的用户?
    如何使用 MySQL 查找今天生日的用户?
    如何使用 MySQL 识别今天生日的用户使用 MySQL 确定今天是否是用户的生日涉及查找生日匹配的所有行今天的日期。这可以通过一个简单的 MySQL 查询来实现,该查询将存储为 UNIX 时间戳的生日与今天的日期进行比较。以下 SQL 查询将获取今天有生日的所有用户: FROM USERS ...
    编程 发布于2024-12-28
  • 在 Go 中使用 WebSocket 进行实时通信
    在 Go 中使用 WebSocket 进行实时通信
    构建需要实时更新的应用程序(例如聊天应用程序、实时通知或协作工具)需要一种比传统 HTTP 更快、更具交互性的通信方法。这就是 WebSockets 发挥作用的地方!今天,我们将探讨如何在 Go 中使用 WebSocket,以便您可以向应用程序添加实时功能。 在这篇文章中,我们将介绍: WebSoc...
    编程 发布于2024-12-28
  • 如何修复 macOS 上 Django 中的“配置不正确:加载 MySQLdb 模块时出错”?
    如何修复 macOS 上 Django 中的“配置不正确:加载 MySQLdb 模块时出错”?
    MySQL配置不正确:相对路径的问题在Django中运行python manage.py runserver时,可能会遇到以下错误:ImproperlyConfigured: Error loading MySQLdb module: dlopen(/Library/Python/2.7/site-...
    编程 发布于2024-12-28
  • 除了“if”语句之外:还有哪些地方可以在不进行强制转换的情况下使用具有显式“bool”转换的类型?
    除了“if”语句之外:还有哪些地方可以在不进行强制转换的情况下使用具有显式“bool”转换的类型?
    无需强制转换即可上下文转换为 bool您的类定义了对 bool 的显式转换,使您能够在条件语句中直接使用其实例“t”。然而,这种显式转换提出了一个问题:“t”在哪里可以在不进行强制转换的情况下用作 bool?上下文转换场景C 标准指定了四种值可以根据上下文转换为的主要场景bool:语句:if、whi...
    编程 发布于2024-12-28
  • 插入数据时如何修复“常规错误:2006 MySQL 服务器已消失”?
    插入数据时如何修复“常规错误:2006 MySQL 服务器已消失”?
    插入记录时如何解决“一般错误:2006 MySQL 服务器已消失”介绍:将数据插入 MySQL 数据库有时会导致错误“一般错误:2006 MySQL 服务器已消失”。当与服务器的连接丢失时会出现此错误,通常是由于 MySQL 配置中的两个变量之一所致。解决方案:解决此错误的关键是调整wait_tim...
    编程 发布于2024-12-28
  • Bootstrap 4 Beta 中的列偏移发生了什么?
    Bootstrap 4 Beta 中的列偏移发生了什么?
    Bootstrap 4 Beta:列偏移的删除和恢复Bootstrap 4 在其 Beta 1 版本中引入了重大更改柱子偏移了。然而,随着 Beta 2 的后续发布,这些变化已经逆转。从 offset-md-* 到 ml-auto在 Bootstrap 4 Beta 1 中, offset-md-*...
    编程 发布于2024-12-28
  • 尽管代码有效,为什么 POST 请求无法捕获 PHP 中的输入?
    尽管代码有效,为什么 POST 请求无法捕获 PHP 中的输入?
    解决 PHP 中的 POST 请求故障在提供的代码片段中:action=''而不是:action="<?php echo $_SERVER['PHP_SELF'];?>";?>"检查 $_POST数组:表单提交后使用 var_dump 检查 $_POST 数...
    编程 发布于2024-12-28
  • 大批
    大批
    方法是可以在对象上调用的 fns 数组是对象,因此它们在 JS 中也有方法。 slice(begin):将数组的一部分提取到新数组中,而不改变原始数组。 let arr = ['a','b','c','d','e']; // Usecase: Extract till index p...
    编程 发布于2024-12-28
  • 如何在 React 中有条件地应用类属性?
    如何在 React 中有条件地应用类属性?
    在 React 中有条件地应用类属性在 React 中,根据从父组件传递的 props 来显示或隐藏元素是很常见的。为此,您可以有条件地应用 CSS 类。然而,当使用语法 {this.props.condition ? 'show' : 'hidden'} 直接在字符...
    编程 发布于2024-12-28
  • 如何在Java中执行系统命令并与其他应用程序交互?
    如何在Java中执行系统命令并与其他应用程序交互?
    Java 中运行进程在 Java 中,启动进程的能力是执行系统命令和与其他应用程序交互的关键功能。为了启动一个进程,Java提供了一个相当于.Net System.Diagnostics.Process.Start方法。解决方案:获取本地路径对于执行至关重要Java 中的进程。幸运的是,Java 的...
    编程 发布于2024-12-28
  • 如何在 C++ 中创建多行字符串文字?
    如何在 C++ 中创建多行字符串文字?
    C 中的多行字符串文字 在 C 中,定义多行字符串文字并不像 Perl 等其他语言那样简单。但是,您可以使用一些技术来实现此目的:连接字符串文字一种方法是利用 C 中相邻字符串文字由编译器连接的事实。通过将字符串分成多行,您可以创建单个多行字符串:const char *text = "...
    编程 发布于2024-12-28
  • 如何准确地透视具有不同记录的数据以避免丢失信息?
    如何准确地透视具有不同记录的数据以避免丢失信息?
    有效地透视不同记录透视查询在将数据转换为表格格式、实现轻松数据分析方面发挥着至关重要的作用。但是,在处理不同记录时,数据透视查询的默认行为可能会出现问题。问题:忽略不同值考虑下表:------------------------------------------------------ | Id ...
    编程 发布于2024-12-27
  • 为什么 C 和 C++ 忽略函数签名中的数组长度?
    为什么 C 和 C++ 忽略函数签名中的数组长度?
    将数组传递给 C 和 C 中的函数 问题:为什么 C 和C 编译器允许在函数签名中声明数组长度,例如 int dis(char a[1])(当它们不允许时)强制执行?答案:C 和 C 中用于将数组传递给函数的语法是历史上的奇怪现象,它允许将指针传递给第一个元素详细说明:在 C 和 C 中,数组不是通...
    编程 发布于2024-12-26

免责声明: 提供的所有资源部分来自互联网,如果有侵犯您的版权或其他权益,请说明详细缘由并提供版权或权益证明然后发到邮箱:[email protected] 我们会第一时间内为您处理。

Copyright© 2022 湘ICP备2022001581号-3