如何访问 Amazon EMR 集群上的 Spark 驱动程序日志?

上次更新日期:2020 年 4 月 13 日

我需要对 Apache Spark 应用程序进行问题排查。如何访问 Amazon EMR 集群上的 Spark 驱动程序日志?

简短描述

在 Amazon EMR 上,Spark 作为 YARN 应用程序运行,并且支持两种部署模式:

  • 客户端模式:默认的部署模式。在客户端模式中,Spark 驱动程序在执行 spark-submit 命令的主机上运行。
  • 集群模式:Spark 驱动程序在应用程序主容器中运行。应用程序主容器是第一个在 Spark 作业执行时运行的容器。

解决方法

客户端模式作业

当您通过在主节点上运行 spark-submit --deploy-mode 客户端来提交 Spark 应用程序时,驱动程序日志显示在终端窗口中。Amazon EMR 在默认情况下不对这些日志进行存档。要捕获日志,请将 spark-submit 命令的输出保存在文件中。例如:

$ spark-submit [--deploy-mode client] ... 1>output.log 2>error.log

当您使用 Amazon EMR 步骤提交 Spark 应用程序时,驱动程序日志将存档到 Amazon Simple Storage Service (Amazon S3) 上的 stderr.gz 文件中。文件路径如下所示:

s3://aws-logs-111111111111-us-east-1/elasticmapreduce/j-35PUYZBQVIJNM/steps/s-2M809TD67U2IA/stderr.gz

有关更多信息,请参阅查看日志文件

将步骤日志下载到 Amazon Elastic Compute Cloud (Amazon EC2) 实例中,然后搜索警告和错误:

1.    下载步骤日志:

aws s3 sync s3://aws-logs-111111111111-us-east-1/elasticmapreduce/j-35PUYZBQVIJNM/steps/s-2M809TD67U2IA/ s-2M809TD67U2IA/

2.    打开步骤日志文件夹:

cd s-2M809TD67U2IA/

3.    解压缩日志文件:

find . -type f -exec gunzip {} \;

4.    从集群模式日志中获取 YARN 应用程序 ID:

grep "Client: Application report for" * | tail -n 1

5.    在客户端模式日志中查找错误和警告:

egrep "WARN|ERROR" *

还可以使用 JupyterHub、Apache Livy 或 Apache Zeppelin 等应用程序提交 Spark 应用程序。这些应用程序会成为将 Spark 应用程序提交至集群的客户端。在此情况下,驱动程序日志存储在主节点上的 /mnt/var/log/ 文件夹中的相应应用程序的日志中。您还可以在以下 Amazon S3 路径中找到压缩日志:

s3://awsexamplebucket/JOBFLOW_ID/node/MASTER_ID/applications/

例如,如果您使用的是 Zeppelin,您可以在 /mnt/var/log/zeppelin/zeppelin-interpreter-spark-xxxxxxxxxx.log 中找到 Spark 驱动程序日志。

注意:对于 Jupyter,驱动程序日志存储在 Livy 日志中:/mnt/var/log/livy/livy-livy-server.out

有关访问应用程序特定日志的更多信息,请参阅查看日志文件

集群模式作业

当您在集群模式下提交 Spark 应用程序时,驱动程序过程在应用程序主容器中运行。应用程序主容器是第一个在 Spark 应用程序执行时运行的容器。客户端将记录 YARN 应用程序报告。要获取驱动程序日志:

1.    从客户端日志中获取应用程序 ID。在下面的示例中,application_1572839353552_0008 是应用程序 ID。

19/11/04 05:24:42 INFO Client: Application report for application_1572839353552_0008 (state: ACCEPTED)

2.    确定应用程序主容器日志。下面是 Spark 应用程序日志的示例列表。在此列表中,container_1572839353552_0008_01_000001 是第一个容器,这表示该容器是应用程序主容器。

s3://aws-logs-111111111111-us-east-1/elasticmapreduce/j-35PUYZBQVIJNM/containers/application_1572839353552_0008/container_1572839353552_0008_01_000001/stderr.gz

s3://aws-logs-111111111111-us-east-1/elasticmapreduce/j-35PUYZBQVIJNM/containers/application_1572839353552_0008/container_1572839353552_0008_01_000001/stdout.gz

s3://aws-logs-111111111111-us-east-1/elasticmapreduce/j-35PUYZBQVIJNM/containers/application_1572839353552_0008/container_1572839353552_0008_01_000002/stderr.gz

s3://aws-logs-111111111111-us-east-1/elasticmapreduce/j-35PUYZBQVIJNM/containers/application_1572839353552_0008/container_1572839353552_0008_01_000002/stdout.gz

3.    将应用程序主容器日志下载到 EC2 实例中:

aws s3 sync s3://aws-logs-111111111111-us-east-1/elasticmapreduce/j-35PUYZBQVIJNM/containers/application_1572839353552_0008/ application_1572839353552_0008/

4.    打开 Spark 应用程序日志文件夹:

cd application_1572839353552_0008/

5.    解压缩日志文件:

find . -type f -exec gunzip {} \;

6.    搜索所有的容器日志,以了解错误和警告:

egrep -Ril "ERROR|WARN" . | xargs egrep "WARN|ERROR"

7.    打开返回在以前的命令输出中的容器日志。

在运行的集群中,您可以使用 YARN CLI 获取 YARN 应用程序容器日志。对于在集群模式中提交的 Spark 应用程序,您可以通过拉取类似以下内容的应用程序主容器日志来访问 Spark 驱动程序日志:

# 1. Get the address of the node that the application master container ran on
$ yarn logs -applicationId application_1585844683621_0001 | grep  'Container: container_1585844683621_0001_01_000001'

20/04/02 19:15:09 INFO client.RMProxy: Connecting to ResourceManager at ip-xxx-xx-xx-xx.us-west-2.compute.internal/xxx.xx.xx.xx:8032
Container: container_1585844683621_0001_01_000001 on ip-xxx-xx-xx-xx.us-west-2.compute.internal_8041

# 2. Use the node address to pull the container logs
$ yarn logs -applicationId application_1585844683621_0001 -containerId container_1585844683621_0001_01_000001 -nodeAddress ip-xxx-xx-xx-xx.us-west-2.compute.internal

这篇文章对您有帮助吗?

我们可以改进什么?


需要更多帮助?