

# 使用 Apache Spark Web UI 监控作业
<a name="monitor-spark-ui"></a>

可以使用 Apache Spark Web UI 监控和调试在 AWS Glue 作业系统上运行的 AWS Glue ETL 作业以及在 AWS Glue 开发终端节点上运行的 Spark 应用程序。可使用 Spark UI 检查每个作业的以下内容：
+ 每个 Spark 阶段的事件时间表
+ 作业的有向非循环图 (DAG)
+ SparkSQL 查询的物理和逻辑计划
+ 每个作业的基础 Spark 环境变量

有关使用 Spark Web UI 的更多信息，请参阅 Spark 文档中的 [Web UI](https://spark.apache.org/docs/3.3.0/web-ui.html)。有关如何解释 Spark UI 结果以提高作业性能的指导，请参阅《AWS 规范性指南》中的 [优化 AWS Glue for Apache Spark 作业性能的最佳实践](https://docs.aws.amazon.com/prescriptive-guidance/latest/tuning-aws-glue-for-apache-spark/introduction.html)。

 您可以在 AWS Glue 控制台中查看 Spark UI。当 AWS Glue 任务在 AWS Glue 3.0 或更高版本上运行，并且日志以标准（而不是传统）格式（对于较新的任务，默认格式为标准）生成时，可以使用此功能。如果您的日志文件大于 0.5 GB，则可以为在 AWS Glue 4.0 或更高版本上运行的任务启用滚动日志支持，以此简化日志存档、分析和故障排除。

您可以使用 AWS Glue 控制台或 AWS Command Line Interface (AWS CLI) 启用 Spark UI。在启用 Spark UI 后，AWS Glue 开发端点上的 AWS Glue ETL 任务和 Spark 应用程序可将 Spark 事件日志备份到您在 Amazon Simple Storage Service (Amazon S3) 中指定的位置。您可以将 Amazon S3 中备份的事件日志与 Spark UI 一起使用，既可以在任务运行时实时使用，也可以在任务完成后使用。日志保留在 Amazon S3 中时，AWS Glue 控制台中的 Spark UI 可以查看它们。

## 权限
<a name="monitor-spark-ui-limitations-permissions"></a>

 要在 AWS Glue 控制台中使用 Spark UI，您可以使用 `UseGlueStudio` 或分别添加所有单独的服务 API。需要所有 API 才能完全使用 Spark UI，不过用户可以通过在其 IAM 权限中添加相关服务 API 来访问相应的 SparkUI 功能，从而实现精细访问控制。

 `RequestLogParsing` 负责执行日志解析，因此最为关键。其余的 API 用于读取相应的解析数据。例如，`GetStages` 将提供对 Spark 作业所有阶段数据的访问权限。

 在示例策略中，映射到 `UseGlueStudio` 的 Spark UI 服务 API 列表如下。以下策略仅提供使用 Spark UI 功能的权限。要添加其他权限（例如 Amazon S3 和 IAM），请参阅 [Creating Custom IAM Policies for AWS Glue Studio](https://docs.aws.amazon.com/glue/latest/dg/getting-started-min-privs.html#getting-started-all-gs-privs.html)。

 在示例策略中，映射到 `UseGlueStudio` 的 Spark UI 服务 API 列表如下。使用 Spark UI 服务 API 时，请使用以下命名空间：`glue:<ServiceAPI>`。

------
#### [ JSON ]

****  

```
{
  "Version":"2012-10-17",		 	 	 
  "Statement": [
    {
      "Sid": "AllowGlueStudioSparkUI",
      "Effect": "Allow",
      "Action": [
        "glue:RequestLogParsing",
        "glue:GetLogParsingStatus",
        "glue:GetEnvironment",
        "glue:GetJobs",
        "glue:GetJob",
        "glue:GetStage",
        "glue:GetStages",
        "glue:GetStageFiles",
        "glue:BatchGetStageFiles",
        "glue:GetStageAttempt",
        "glue:GetStageAttemptTaskList",
        "glue:GetStageAttemptTaskSummary",
        "glue:GetExecutors",
        "glue:GetExecutorsThreads",
        "glue:GetStorage",
        "glue:GetStorageUnit",
        "glue:GetQueries",
        "glue:GetQuery"
      ],
      "Resource": [
        "*"
      ]
    }
  ]
}
```

------

## 限制
<a name="monitor-spark-ui-limitations"></a>
+ AWS Glue 控制台中的 Spark UI 不适用于 2023 年 11 月 20 日之前的任务运行，因为此类任务采用旧版日志格式。
+  AWS Glue 控制台中的 Spark UI 支持为 AWS Glue 4.0 启用滚动日志，例如流式处理任务中默认生成的日志。所有生成的滚动日志事件文件的最大总和为 2 GB。对于不支持滚动日志的 AWS Glue 任务，SparkUI 支持的日志事件文件最大大小为 0.5 GB。
+  如果 Spark 事件日志存储在只能由您的 VPC 访问的 Amazon S3 存储桶中，则无服务器 Spark UI 不适用于此类日志。

## 示例：Apache Spark Web UI
<a name="monitor-spark-ui-limitations-example"></a>

此示例演示了如何使用 Spark UI 了解任务性能。屏幕截图显示了由自行管理的 Spark 历史记录服务器提供的 Spark Web UI。AWS Glue 控制台中的 Spark UI 提供了类似视图。有关使用 Spark Web UI 的更多信息，请参阅 Spark 文档中的 [Web UI](https://spark.apache.org/docs/3.3.0/web-ui.html)。

以下是一个示例 Spark 应用程序，其从两个数据源读取数据，执行联接转换，并以 Parquet 格式将其写入 Amazon S3。

```
import sys
from awsglue.transforms import *
from awsglue.utils import getResolvedOptions
from pyspark.context import SparkContext
from awsglue.context import GlueContext
from awsglue.job import Job
from pyspark.sql.functions import count, when, expr, col, sum, isnull
from pyspark.sql.functions import countDistinct
from awsglue.dynamicframe import DynamicFrame
 
args = getResolvedOptions(sys.argv, ['JOB_NAME'])
 
sc = SparkContext()
glueContext = GlueContext(sc)
spark = glueContext.spark_session
 
job = Job(glueContext)
job.init(args['JOB_NAME'])
 
df_persons = spark.read.json("s3://awsglue-datasets/examples/us-legislators/all/persons.json")
df_memberships = spark.read.json("s3://awsglue-datasets/examples/us-legislators/all/memberships.json")
 
df_joined = df_persons.join(df_memberships, df_persons.id == df_memberships.person_id, 'fullouter')
df_joined.write.parquet("s3://aws-glue-demo-sparkui/output/")
 
job.commit()
```

以下 DAG 可视化显示此 Spark 作业中的各个阶段。

![\[Spark UI 的屏幕截图，显示了作业 0 的 2 个已完成阶段。\]](http://docs.aws.amazon.com/zh_cn/glue/latest/dg/images/spark-ui1.png)


以下作业事件时间表显示了各个 Spark 执行程序的启动、执行和终止。

![\[Spark UI 的屏幕截图，显示了各个 Spark 执行程序的已完成、失败和活动阶段。\]](http://docs.aws.amazon.com/zh_cn/glue/latest/dg/images/spark-ui2.png)


以下屏幕显示了 SparkSQL 查询计划的详细信息：
+ 已解析的逻辑计划
+ 已分析的逻辑计划
+ 已优化的逻辑计划
+ 执行的物理计划

![\[SparkSQL 查询计划：已解析、已分析和已优化的逻辑计划以及执行的物理计划。\]](http://docs.aws.amazon.com/zh_cn/glue/latest/dg/images/spark-ui3.png)


**Topics**
+ [权限](#monitor-spark-ui-limitations-permissions)
+ [限制](#monitor-spark-ui-limitations)
+ [示例：Apache Spark Web UI](#monitor-spark-ui-limitations-example)
+ [为 AWS Glue 作业启用 Apache Spark Web UI](monitor-spark-ui-jobs.md)
+ [启动 Spark 历史记录服务器](monitor-spark-ui-history.md)

# 为 AWS Glue 作业启用 Apache Spark Web UI
<a name="monitor-spark-ui-jobs"></a>

您可以使用 Apache Spark Web UI 监控和调试在 AWS Glue 作业系统上运行的 AWS Glue ETL 作业。您可以使用 AWS Glue 控制台或 AWS Command Line Interface (AWS CLI) 配置 Spark UI。

AWS Glue 每 30 秒将 Spark 事件日志备份到您指定的 Amazon S3 路径一次。

**Topics**
+ [配置 Spark UI（控制台）](#monitor-spark-ui-jobs-console)
+ [配置 Spark UI (AWS CLI)](#monitor-spark-ui-jobs-cli)
+ [为使用笔记本的会话配置 Spark 用户界面](#monitor-spark-ui-sessions)
+ [启用滚动日志](#monitor-spark-ui-rolling-logs)

## 配置 Spark UI（控制台）
<a name="monitor-spark-ui-jobs-console"></a>

按照以下步骤使用 AWS 管理控制台 配置 Spark UI。创建 AWS Glue 任务后，将默认启用 Spark UI。

**在创建或编辑任务时启用 Spark UI**

1. 登录 AWS 管理控制台，然后打开 AWS Glue 控制台，网址为：[https://console.aws.amazon.com/glue/](https://console.aws.amazon.com/glue/)。

1. 在导航窗格中，选择**作业**。

1. 选择**添加作业**，或选择现有的作业。

1. 在**作业详细信息**中，打开**高级属性**。

1. 在 **Spark UI** 选项卡下，选择**将 Spark UI 日志写入 Amazon S3**。

1. 指定用于存储任务的 Spark 事件日志的 Amazon S3 路径。请注意，如果您在任务中使用安全配置，则加密也将适用于 Spark UI 日志文件。有关更多信息，请参阅 [加密 AWS Glue 写入的数据](encryption-security-configuration.md)。

1. 在 **Spark UI 日志记录和监控配置**下：
   + 如果要生成可在 AWS Glue 控制台中查看的日志，请选择**标准**。
   + 如果要生成可在 Spark 历史记录服务器上查看的日志，请选择**传统**。
   + 您还可以选择同时生成这两种日志。

## 配置 Spark UI (AWS CLI)
<a name="monitor-spark-ui-jobs-cli"></a>

要生成可在 AWS Glue 控制台中使用 Spark UI 查看的日志，请使用 AWS CLI 将以下任务参数传递给 AWS Glue 任务。有关更多信息，请参阅 [在 AWS Glue 作业中使用作业参数](aws-glue-programming-etl-glue-arguments.md)。

```
'--enable-spark-ui': 'true',
'--spark-event-logs-path': 's3://s3-event-log-path'
```

要将日志分发到其遗留位置，请将 `--enable-spark-ui-legacy-path` 参数设置为 `"true"`。如果不需要同时生成两种格式的日志，请移除 `--enable-spark-ui` 参数。

## 为使用笔记本的会话配置 Spark 用户界面
<a name="monitor-spark-ui-sessions"></a>

**警告**  
AWS Glue 交互式会话目前不支持在控制台中使用 Spark UI。配置 Spark 历史记录服务器。

 如果您使用 AWS Glue 笔记本电脑，请在开始会话之前设置 SparkUI 配置。为此，请使用 `%%configure` 单元格魔术命令：

```
%%configure { “--enable-spark-ui”: “true”, “--spark-event-logs-path”: “s3://path” }
```

## 启用滚动日志
<a name="monitor-spark-ui-rolling-logs"></a>

 为 AWS Glue 任务启用 SparkUI 和滚动日志事件文件有以下优势：
+  滚动日志事件文件 – 启用滚动日志事件文件后，AWS Glue 会为任务执行的每个步骤生成单独的日志文件，以便用户更轻松地识别和排查特定阶段或转换的问题。
+  更好的日志管理 – 滚动日志事件文件有助于更有效地管理日志文件。与存储可能较大的单个日志文件不同，启用滚动日志事件文件后，日志会根据任务执行阶段拆分为更小、更易于管理的多个文件。这可以简化日志存档、分析和故障排除。
+  提高容错能力 – 如果 AWS Glue 任务失败或中断，滚动日志事件文件可以提供有关最后成功阶段的宝贵信息，从而帮助您更轻松地从该阶段恢复任务，而不是从头开始。
+  成本优化 – 通过启用滚动日志事件文件，您可以节省与日志文件相关的存储成本。与存储可能较大的单一日志文件不同，您能够存储更小、更易于管理的多个日志文件，这可能更具成本效益，特别是对于长时间运行或复杂的任务而言。

 在新环境中，用户可以通过以下方式明确启用滚动日志：

```
'—conf': 'spark.eventLog.rolling.enabled=true'
```

或

```
'—conf': 'spark.eventLog.rolling.enabled=true —conf 
spark.eventLog.rolling.maxFileSize=128m'
```

 激活滚动日志时，`spark.eventLog.rolling.maxFileSize` 会指定事件日志文件在滚动之前的最大大小。如果未指定此可选参数，则默认值为 128 MB。最小为 10 MB。

 所有生成的滚动日志事件文件的最大总和为 2 GB。对于不支持滚动日志的 AWS Glue 任务，SparkUI 支持的日志事件文件最大大小为 0.5 GB。

您可以通过传递额外配置来关闭流式处理任务的滚动日志功能。请注意，非常大的日志文件的维护成本可能很高。

要关闭滚动日志，请提供以下配置：

```
'--spark-ui-event-logs-path': 'true',
'--conf': 'spark.eventLog.rolling.enabled=false'
```

# 启动 Spark 历史记录服务器
<a name="monitor-spark-ui-history"></a>

您可以使用 Spark 历史记录服务器在自己的基础设施上可视化显示 Spark 日志。对于在 AWS Glue 4.0 或更高版本上运行并以标准（而不是传统）格式生成日志的 AWS Glue 任务，您可以在 AWS Glue 控制台中看到相同的可视化效果。有关更多信息，请参阅 [使用 Apache Spark Web UI 监控作业](monitor-spark-ui.md)。

您可以使用在 EC2 实例上托管服务器的 AWS CloudFormation 模板启动 Spark 历史记录服务器，也可以使用 Docker 在本地启动 Spark 历史记录服务器。

**Topics**
+ [使用 AWS CloudFormation 启动 Spark 历史记录服务器并查看 Spark UI](#monitor-spark-ui-history-cfn)
+ [使用 Docker 启动 Spark 历史记录服务器并查看 Spark UI](#monitor-spark-ui-history-local)

## 使用 AWS CloudFormation 启动 Spark 历史记录服务器并查看 Spark UI
<a name="monitor-spark-ui-history-cfn"></a>

您可以使用 AWS CloudFormation 模板启动 Apache Spark 历史记录服务器并查看 Spark Web UI。这些模板是您应修改以满足要求的示例。

**使用 CloudFormation 启动 Spark 历史记录服务器并查看 Spark UI**

1. 选择下表中的 **Launch Stack (启动堆栈)** 按钮之一。这将在 CloudFormation 控制台上启动堆栈。    
[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/glue/latest/dg/monitor-spark-ui-history.html)

1. 在 **Specify template (指定模板)** 页面上，选择 **Next (下一步)**。

1. 在 **Specify Stack details (指定堆栈详细信息)** 页面上，输入 **Stack name (堆栈名称)**。在 **Parameters**（参数）下输入其他信息。

   1. 

**Spark UI 配置**

      提供以下信息：
      + **IP address range (IP 地址范围)** – 可用于查看 Spark UI 的 IP 地址范围。如果要限制来自特定 IP 地址范围的访问，则应使用自定义值。
      + **History server port (历史记录服务器端口)** – 用于 Spark UI 的端口。您可以使用默认值。
      + **Event log directory (事件日志目录)** – 选择用于存储来自 AWS Glue 任务或开发终端节点的 Spark 事件日志的位置。您必须将 **s3a://** 用于事件日志路径模式。
      + **Spark package location (Spark 包位置)** – 可以使用默认值。
      + **Keystore path (密钥库路径)** – HTTPS 的 SSL/TLS 密钥库路径。如果要使用自定义密钥库文件，则可在此处指定 S3 路径 `s3://path_to_your_keystore_file`。如果将此参数保留为空，则会生成并使用基于自签名证书的密钥库。
      + **Keystore password**（密钥库密码）– 输入 HTTPS 的 SSL/TLS 密钥库密码。

   1. 

**EC2 实例配置**

      提供以下信息：
      + **Instance type (实例类型)** – 托管 Spark 历史记录服务器的 Amazon EC2 实例的类型。由于此模板在您的账户中启动 Amazon EC2 实例，因此，将向您的账户单独收取 Amazon EC2 费用。
      + **Latest AMI ID (最新 AMI ID)** – Spark 历史记录服务器实例的 Amazon Linux 2 的 AMI ID。您可以使用默认值。
      + **VPC ID** – Spark 历史记录服务器实例的 Virtual Private Cloud（VPC）ID。可以使用您的账户中可用的任何 VPC。建议不要将默认 VPC 用于[默认网络 ACL](https://docs.aws.amazon.com/vpc/latest/userguide/vpc-network-acls.html#default-network-acl)。有关更多信息，请参阅《Amazon VPC 用户指南》**中的[默认 VPC 与默认子网](https://docs.aws.amazon.com/vpc/latest/userguide/default-vpc.html)和[创建 VPC](https://docs.aws.amazon.com/vpc/latest/userguide/working-with-vpcs.html#Create-VPC)。
      + **Subnet ID (子网 ID)** – Spark 历史记录服务器实例的 ID。您可以使用 VPC 中的任意子网。您必须能够从客户端访问子网。如果要通过 Internet 访问，则必须使用在路由表中具有 Internet 网关的公有子网。

   1. 选择**下一步**。

1. 在 **Configure stack options**（配置堆栈选项）页面上，要使用当前用户凭证确定 CloudFormation 如何在堆栈中创建、修改或删除资源，请选择 **Next**（下一步）。您还可以在**权限**部分中指定要使用的角色，而不是当前用户权限，然后选择**下一步**。

1. 在 **Review (检查)** 页面上，检查模板。

   选择 **I acknowledge that CloudFormation might create IAM resources (我确认 Amazon CloudFormation 可能创建 IAM 资源)**，然后选择 **Create stack (创建堆栈)**。

1. 等待创建堆栈。

1. 打开 **Outputs (输出)** 选项卡。

   1. 如果您使用的是公有子网，请复制 **SparkUiPublicUrl** 的 URL。

   1. 如果您使用的是私有子网，请复制 **SparkUiPrivateUrl** 的 URL。

1. 打开 Web 浏览器，然后将 URL 粘贴到其中。这样一来，您便能在指定端口上使用 HTTPS 访问服务器。您的浏览器可能无法识别服务器的证书，在这种情况下，您必须重写其保护并继续进行。

## 使用 Docker 启动 Spark 历史记录服务器并查看 Spark UI
<a name="monitor-spark-ui-history-local"></a>

如果您更喜欢本地访问（不需要 Apache Spark 历史记录服务器的 EC2 实例），也可以使用 Docker 启动 Apache Spark 历史记录服务器并在本地查看 Spark UI。此 Dockerfile 是一个示例，您应修改该示例以满足您的要求。

 **先决条件** 

有关如何在笔记本电脑上安装 Docker 的信息，请参阅 [Docker Engine 社区](https://docs.docker.com/install/)。

**使用 Docker 启动 Spark 历史记录服务器并在本地查看 Spark UI**

1. 从 GitHub 下载文件。

   从 [ AWS Glue 代码示例](https://github.com/aws-samples/aws-glue-samples/tree/master/utilities/Spark_UI/)下载 Dockerfile 和 `pom.xml`。

1. 确定是要使用您的用户凭证还是联合身份用户凭证来访问 AWS。
   + 要使用当前用户凭证访问 AWS，请获取要用于 `docker run` 命令中的 ` AWS_ACCESS_KEY_ID` 和 `AWS_SECRET_ACCESS_KEY` 的值。有关更多信息，请参阅《 IAM 用户指南》**中的[管理 IAM 用户的访问密钥](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_access-keys.html)。
   + 要使用 SAML 2.0 联合身份用户访问 AWS，请获取 ` AWS_ACCESS_KEY_ID`、`AWS_SECRET_ACCESS_KEY` 和 ` AWS_SESSION_TOKEN` 的值。有关更多信息，请参阅 [请求临时安全凭证](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_request.html)。

1. 确定事件日志目录的位置，以在 `docker run` 命令中使用。

1. 使用名称 ` glue/sparkui` 和标签 `latest` 以及本地目录中的文件构建 Docker 镜像。

   ```
   $ docker build -t glue/sparkui:latest . 
   ```

1. 创建并开启 docker 容器。

   在以下命令中，使用先前在步骤 2 和步骤 3 中获得的值。

   1. 要使用您的用户凭证创建 docker 容器，请使用类似于以下内容的命令

      ```
      docker run -itd -e SPARK_HISTORY_OPTS="$SPARK_HISTORY_OPTS -Dspark.history.fs.logDirectory=s3a://path_to_eventlog
       -Dspark.hadoop.fs.s3a.access.key=AWS_ACCESS_KEY_ID -Dspark.hadoop.fs.s3a.secret.key=AWS_SECRET_ACCESS_KEY"
       -p 18080:18080 glue/sparkui:latest "/opt/spark/bin/spark-class org.apache.spark.deploy.history.HistoryServer"
      ```

   1. 要使用临时凭证创建 docker 容器，请使用 ` org.apache.hadoop.fs.s3a.TemporaryAWSCredentialsProvider` 作为提供程序，并提供在步骤 2 中获得的凭证值。有关更多信息，请参阅 *Hadoop：与 Amazon Web Services 集成*文档中的 [将会话凭证与 TemporaryAWSCredentialsProvider 配合使用](https://hadoop.apache.org/docs/stable/hadoop-aws/tools/hadoop-aws/index.html#Using_Session_Credentials_with_TemporaryAWSCredentialsProvider)。

      ```
      docker run -itd -e SPARK_HISTORY_OPTS="$SPARK_HISTORY_OPTS -Dspark.history.fs.logDirectory=s3a://path_to_eventlog
       -Dspark.hadoop.fs.s3a.access.key=AWS_ACCESS_KEY_ID -Dspark.hadoop.fs.s3a.secret.key=AWS_SECRET_ACCESS_KEY
       -Dspark.hadoop.fs.s3a.session.token=AWS_SESSION_TOKEN
       -Dspark.hadoop.fs.s3a.aws.credentials.provider=org.apache.hadoop.fs.s3a.TemporaryAWSCredentialsProvider"
       -p 18080:18080 glue/sparkui:latest "/opt/spark/bin/spark-class org.apache.spark.deploy.history.HistoryServer"
      ```
**注意**  
这些配置参数来自 [ Hadoop-AWS模块](https://hadoop.apache.org/docs/stable/hadoop-aws/tools/hadoop-aws/index.html)。您可能需要根据自己的使用案例添加特定的配置。例如：隔离区域的用户需要配置 ` spark.hadoop.fs.s3a.endpoint`。

1. 在浏览器中打开 `http://localhost:18080` 以在本地查看 Spark UI。