用最专业的眼光看待互联网
立即咨询关键要点
Amazon EMR Serverless 允许用户在不管理集群的情况下运行开源大数据框架。新推出的 CloudWatch 监控功能能够近乎实时地监控 EMR Serverless 工作节点的资源利用情况。本文将介绍如何通过 CloudWatch 指标来监控 EMR Serverless 工作节点,以优化资源利用、识别错误并进行故障排查。Amazon EMR Serverless 使用户能够运行如 Apache Spark 和 Apache Hive 等开源大数据框架,而无需管理任何集群和服务器。利用 EMR Serverless,用户可以在任何规模下运行分析工作负载,系统会自动扩展资源以秒级响应数据量和处理要求的变化。
我们新推出了适用于 EMR Serverless 的工作指标,可以在 Amazon CloudWatch 中监控 Spark 和 Hive 作业的 vCPU、内存、临时存储及磁盘 I/O 分配和使用情况。
本文是关于 EMR Serverless 完整性的系列文章之一,将讨论如何使用这些 CloudWatch 指标在近乎实时的基础上监控 EMR Serverless 工作节点。
在每个 Spark 作业层级,EMR Serverless 向 CloudWatch 生成以下新指标,涵盖驱动程序和执行器。这些指标提供了作业性能、瓶颈和资源利用的详细洞察。
指标名称描述WorkerCpuAllocated作业运行期间分配给工作节点的 vCPU 核心总数WorkerCpuUsed作业运行期间工作节点实际使用的 vCPU 核心总数WorkerMemoryAllocated作业运行期间分配给工作节点的内存总量GBWorkerMemoryUsed作业运行期间工作节点实际使用的内存总量GBWorkerEphemeralStorageAllocated作业运行期间为工作节点分配的临时存储字节数WorkerEphemeralStorageUsed作业运行期间工作节点实际使用的临时存储字节数WorkerStorageReadBytes作业运行期间工作节点从存储中读取的字节数WorkerStorageWriteBytes作业运行期间工作节点写入存储的字节数为了进一步增强这种可监控性体验,我们创建了一个解决方案,将 EMR Serverless 应用程序的所有指标集中在一个 CloudWatch 仪表板上。每个 EMR Serverless 应用程序需要启动一个 AWS CloudFormation 模板。您可以使用同一个 CloudWatch 仪表板监控所有提交到单个 EMR Serverless 应用程序的作业。如需了解更多关于该仪表板的信息以及如何将该解决方案部署到您的帐户中,请参阅 EMR Serverless CloudWatch Dashboard GitHub 仓库。
在接下来的部分中,我们将逐步介绍如何使用该仪表板进行以下操作:
优化资源利用,以在不影响作业性能的情况下节省成本诊断常见错误造成的故障,同时无需深入日志文件,以便有效解决这些错误要运行本文提供的示例作业,您需要使用 AWS 管理控制台 或 AWS 命令行界面(AWS CLI) 创建一个默认设置的 EMR Serverless 应用程序,然后根据提供的 EMR Serverless 应用程序 ID 启动 GitHub 仓库 中的 CloudFormation 模板。
您需要将本文中的所有作业提交到同一个 EMR Serverless 应用程序。如果您想监控其他应用程序,可以为自己的 EMR Serverless 应用程序 ID 部署此模板。
在运行 Spark 作业时,您通常从默认配置开始。没有对实际资源利用情况的可视化支持,优化工作负载往往充满挑战。我们注意到客户经常调整的一些最常见配置包括 sparkdrivercores、sparkdrivermemory、sparkexecutorcores 和 sparkexecutormemory。
为了展示新添加的 CloudWatch 仪表板的工作节点级别指标如何帮助您微调作业配置以实现更好的性价比和资源利用率,让我们运行以下 Spark 作业,利用 NOAA 综合地面数据库 (ISD) 数据集进行一些转换和聚合。
请使用以下命令在 EMR Serverless 中运行该作业。提供您的 Amazon Simple Storage ServiceAmazon S3存储桶和启动 CloudFormation 模板所用的 EMR Serverless 应用程序 ID。确保使用相同的应用程序 ID 提交本文中的所有示例作业。此外,提供一个 AWS 身份与访问管理 (IAM) 运行角色。
bashaws emrserverless startjobrun name emrscwdashboardtest1 applicationid ltAPPLICATIONIDgt executionrolearn ltJOBROLEARNgt jobdriver {sparkSubmit {entryPoint s3//ltBUCKETNAMEgt/scripts/windycitypyentryPointArguments [s3//noaaglobalhourlypds/2024/ s3//ltBUCKETNAMEgt/emrscwdashboardtest1/]} }
现在,让我们在 CloudWatch 仪表板中检查执行器的 vCPU 和内存使用情况。
作业以默认 EMR Serverless Spark 配置提交。从前面的截图中的 Executor CPU Allocated 指标来看,该作业总共被分配了 396 个 vCPU99 个执行器 每个执行器 4 个 vCPU。但是,通过 Executor CPU Used 可以看出,该作业最多只使用了 110 个 vCPU。这表明 vCPU 资源存在超额分配。同样,该作业总共被分配了 1584GB 内存,根据 Executor Memory Used 指标,我们发现作业在运行期间仅使用了 176GB 内存,表明内存资源也存在过度分配。
接下来,让我们使用以下调整后的配置重新运行此作业。
原始作业默认配置重新运行作业调整配置sparkexecutormemory14 GBsparkexecutorcores4sparkdynamicAllocationmaxExecutors99总资源利用6521 vCPU 小时、26084 内存 GB 小时、32606 存储 GB 小时可计费资源利用7046 vCPU 小时、28182 内存 GB 小时、0 存储 GB 小时我们使用以下代码:
bashaws emrserverless startjobrun name emrscwdashboardtest2 applicationid ltAPPLICATIONIDgt executionrolearn ltJOBROLEARNgt jobdriver {sparkSubmit {entryPoint s3//ltBUCKETNAMEgt/scripts/windycitypyentryPointArguments [s3//noaaglobalhourlypds/2024/ s3//ltBUCKETNAMEgt/emrscwdashboardtest2/]sparkSubmitParameters conf sparkdrivercores=2 conf sparkdrivermemory=3g conf sparkexecutormemory=3g conf sparkexecutorcores=2 conf sparkdynamicAllocationmaxExecutors=30} }
让我们再次从 CloudWatch 仪表板检查这次作业运行的执行器指标。
在第二个作业中,我们看到 vCPU396 vs 60和内存1584 GB vs 120 GB的分配都减少,期待结果是更好的资源利用。第一个作业运行了 4 分 41 秒,第二个作业耗时 4 分 54 秒。此重新配置已实现 79 的成本节约,而作业性能未受到影响。
您可以利用这些指标进一步优化您的作业,通过增加或减少工作节点数量或分配的资源。
通过 CloudWatch 仪表板,您可以快速诊断由于 CPU、内存和存储等问题引起的作业失败,例如内存不足或设备上没有剩余空间。这使您能够快速识别并解决常见错误,而无需检查日志或浏览 Spark 历史服务器。此外,由于可以从仪表板检查资源利用情况,您可以按需调整配置,将所需资源增加到最小限度,以避免资源的过度分配,从而进一步节省成本。
为了说明此用例,让我们运行以下 Spark 作业,该作业创建一个包含几百万行的庞大 Spark 数据框。通常,此操作由 Spark 驱动程序执行。在提交作业时,我们还配置了 sparkrpcmessagemaxSize,这是处理大量列数据框任务序列化所要求的。
bashaws emrserverless startjobrun name emrscwdashboardtest3 applicationid ltAPPLICATIONIDgt executionrolearn ltJOBROLEARNgt jobdriver {sparkSubmit {entryPoint s3//ltBUCKETNAMEgt/scripts/createlargediskpysparkSubmitParameters conf sparkrpcmessagemaxSize=2000} }
几分钟后,该作业失败,并在 作业详情 部分中显示“释放容器时遇到错误”的错误信息。
当遇到不具描述性的错误消息时,进一步调查变得至关重要,我们需要检查驱动程序和执行器日志以进行故障排查。不过,在深入日志之前,让我们首先查看 CloudWatch 仪表板,尤其是驱动程序指标,因为释放容器通常由驱动程序执行。
我们可以看到 Driver CPU Used 和 Driver Storage Used 的数值均在其分配值范围内。但检查 Driver Memory Allocated 和 Driver Memory Used 后发现,驱动程序使用了分配给它的全部 16GB 内存。默认情况下,EMR Serverless 驱动程序的内存分配为 16GB。
让我们重新运行该作业,给驱动程序分配更多内存。首先将驱动程序内存设置为 27GB,因为 sparkdrivermemory sparkdrivermemoryOverhead 的总值应小于 30GB,以确保正常运行。sparkrpcmessagemaxSize 将保持不变。

bashaws emrserverless startjobrun name emrscwdashboardtest4 applicationid ltAPPLICATIONIDgt executionrolearn ltJOBROLEARNgt jobdriver {sparkSubmit {entryPoint s3//ltBUCKETNAMEgt/scripts/createlargediskpysparkSubmitParameters conf sparkdrivermemory=27G conf sparkrpcmessagemaxSize=2000} }
这次作业成功完成。让我们查看 CloudWatch 仪表板以观察驱动程序内存利用情况。
如上图所示,当前的内存分配为 30GB,但作业运行期间,驱动程序内存利用率没有超过 21GB。因此,我们可以在这里进一步优化成本,将 sparkdrivermemory 的值降低。我们使用设置为 22GB 重新运行相同的作业,作业仍然成功,同时驱动程序内存利用率得到了提升。
使用 CloudWatch 进行监控非常适合诊断驱动程序相关的问题,因为每个作业只有一个驱动程序,而驱动程序使用的实际资源就是这一单一驱动程序的资源使用情况。相对而言,执行器指标是汇总在所有工作节点上的。不过,您可以利用该仪表板为作业提供适当数量的资源,以确保作业成功,从而避免资源的过度分配。
魔戒官网梯子举个例子,让我们运行以下 Spark 作业,该作业通过处理多年的超大 NOAA 数据集来模拟所有工作节点上的磁盘超利用率。该作业还会暂时将一个非常大的数据框缓存到磁盘上。
bashaws emrserverless startjobrun name emrscwdashboardtest5 applicationid ltAPPLICATIONIDgt executionrolearn ltJOBROLEARNgt jobdriver {sparkSubmit {entryPoint s3//ltBUCKETNAMEgt/scripts/noaadiskpy} }
几分钟后,我们看到该作业的 作业详情 部分显示“设备空间不足”的错误,表明某些工作节点的磁盘空间耗尽。
检查仪表板的 Running Executors 指标,我们发现有 99 个执行器正在运行。每个工作节点的默认存储为 20GB。
因为这是一个 Spark 任务失败,让我们从仪表板检查 Executor Storage Allocated 和 Executor Storage Used 指标因为驱动程序不会执行任何任务。
![CloudWatch 执行节点磁盘使用情况](https//d2908q01vomqb2cloudfrontnet