

# AWS Glue Spark 和 PySpark 作业
<a name="spark_and_pyspark"></a>

AWS Glue 支持 Spark 和 PySpark 作业。Spark 任务会在由 AWS Glue 托管的 Apache Spark 环境中执行。它将批量处理数据。流式处理 ETL 作业与 Spark 作业类似，只不过前者在数据流上执行 ETL。它使用 Apache Spark Structured Streaming 框架。某些 Spark 作业功能不可用于流式处理 ETL 作业。

以下几个部分提供有关 AWS Glue Spark 和 PySpark 作业的信息。

**Topics**
+ [在 AWS Glue 中为 Spark 作业配置作业属性](add-job.md)
+ [在 AWS Glue 控制台中编辑 Spark 脚本](edit-script-spark.md)
+ [作业（旧版）](console-edit-script.md)
+ [使用作业书签跟踪已处理的数据](monitor-continuations.md)
+ [存储 Spark 随机排序数据](monitor-spark-shuffle-manager.md)
+ [监控 AWS Glue Spark 作业](monitor-spark.md)
+ [AWS 中 Apache Spark 的生成式人工智能故障排除](troubleshoot-spark.md)
+ [通过 AWS Glue 使用实体化视图](materialized-views.md)

# 在 AWS Glue 中为 Spark 作业配置作业属性
<a name="add-job"></a>

当您在 AWS Glue 控制台中定义任务时，您会提供属性的值来控制 AWS Glue 的运行时环境。

## 定义 Spark 作业的作业属性
<a name="create-job"></a>

以下列表描述了 Spark 作业的属性。有关 Python Shell 作业的属性，请参阅 [定义 Python shell 作业的作业属性](add-job-python.md#create-job-python-properties)。有关流式处理 ETL 作业的属性，请参阅 [定义串流 ETL 作业的作业属性](add-job-streaming.md#create-job-streaming-properties)。

属性将按照在 AWS Glue 控制台上的 **Add job (添加任务)** 向导中显示的顺序列出。

**名称**  
提供最大长度为 255 个字符的 UTF-8 字符串。

**说明**  
可选的描述最长为 2048 个字符。

**IAM 角色**  
指定用来为用于运行任务和访问数据存储的资源进行授权的 IAM 角色。有关在 AWS Glue 中运行作业的权限的更多信息，请参阅 [适用于 AWS Glue 的 Identity and Access Management](security-iam.md)。

**Type**  
ETL 作业的类型。这将根据您选择的数据来源类型自动设置。  
+ **Spark** 会使用作业命令 `glueetl` 运行 Apache Spark ETL 脚本。
+ **Spark 流式处理**使用作业命令 `gluestreaming` 运行 Apache Spark 流式处理 ETL 脚本。有关更多信息，请参阅 [在 AWS Glue 中流式处理 ETL 作业](add-job-streaming.md)。
+ **Python Shell** 使用作业命令 `pythonshell` 运行 Python 脚本。有关更多信息，请参阅 [在 AWS Glue 中为 Python shell 作业配置作业属性](add-job-python.md)。

** AWS Glue 版本**  
AWS Glue 版本决定了可用于任务的 Apache Spark 和 Python 的版本，如下表中所述。      
<a name="table-glue-versions"></a>[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/glue/latest/dg/add-job.html)

**语言**  
ETL 脚本中的代码定义了作业的逻辑。该脚本可以用 Python 或 Scala 进行编码。您可以选择作业运行的脚本是由 AWS Glue 生成还是由您提供。您需要在 Amazon Simple Storage Service（Amazon S3）中提供脚本名称和位置。确认没有与路径中的脚本目录同名的文件。要了解有关编写脚本的更多信息，请参阅 [AWS Glue 编程指南](edit-script.md)。

**Worker 类型**  
以下工作线程类型可供使用：  
AWS Glue 工作线程上可用的资源以 DPU 为单位进行衡量。DPU 是对处理能力的相对度量，它由 4 个 vCPU 的计算容量和 16GB 内存组成。  
+ **G.025X** – 当您选择这种类型时，您还提供了 **Number of workers (工件数量)** 的值。每个工作线程映射到 0.25 个 DPU（2 个 vCPU，4GB 内存）和 84GB 磁盘（大约 34GB 可用空间）。我们建议为低容量串流任务使用此 Worker 类型。此工作线程类型仅适用于 AWS Glue 版本 3.0 或更高版本的流式处理作业。
+ **G.1X** – 当您选择这种类型时，您还提供了 **Number of workers (工件数量)** 的值。每个 Worker 映射到 1 个 DPU（4 个 vCPU，16 GB 内存）和 94 GB 磁盘（大约 44 GB 可用空间）。我们建议将这种工作线程类型用于数据转换、联接和查询等工作负载，以提供一种可扩展且经济实惠的方式来运行大多数作业。
+ **G.2X** – 当您选择这种类型时，您还提供了 **Number of workers (工件数量)** 的值。每个 Worker 映射到 2 个 DPU（8 个 vCPU，32 GB 内存）和 138 GB 磁盘（大约 78 GB 可用空间）。我们建议将这种工作线程类型用于数据转换、联接和查询等工作负载，以提供一种可扩展且经济实惠的方式来运行大多数作业。
+ **G.4X** – 当您选择这种类型时，您还提供了 **Number of workers (工件数量)** 的值。每个 Worker 映射到 4 个 DPU（16 个 vCPU，64 GB 内存）和 256 GB 磁盘（大约 230 GB 可用空间）。对于工作负载包含要求最高的转换、聚合、联接和查询的作业，我们建议使用这种工作线程类型。
+ **G.8X** – 当您选择这种类型时，您还提供了 **Number of workers (工件数量)** 的值。每个 Worker 映射到 8 个 DPU（32 个 vCPU，128 GB 内存）和 512 GB 磁盘（大约 485 GB 可用空间）。对于工作负载包含要求最高的转换、聚合、联接和查询的作业，我们建议使用这种工作线程类型。
+ **G.12X** – 当您选择这种类型时，您还提供了 **Number of workers (工件数量)** 的值。每个 Worker 映射到 12 个 DPU（48 个 vCPU，192 GB 内存）和 768 GB 磁盘（大约 741 GB 可用空间）。对于工作负载非常大、资源密集型且需要大量计算容量的作业，我们建议使用此 Worker 类型。
+ **G.16X** – 当您选择这种类型时，您还提供了 **Number of workers (工件数量)** 的值。每个 Worker 映射到 16 个 DPU（64 个 vCPU，256 GB 内存）和 1024 GB 磁盘（大约 996 GB 可用空间）。对于工作负载最大、资源最密集且需要最大计算容量的作业，我们建议使用此 Worker 类型。
+ **R.1X** – 当您选择这种类型时，您还提供了 **Number of workers (工件数量)** 的值。每个 Worker 映射到 1 个 DPU（配置经过内存优化）。对于经常遇到内存不足错误或需要高内存与 CPU 比率的内存密集型工作负载，我们建议使用此 Worker 类型。
+ **R.2X** – 当您选择这种类型时，您还提供了 **Number of workers (工件数量)** 的值。每个 Worker 映射到 2 个 DPU（配置经过内存优化）。对于经常遇到内存不足错误或需要高内存与 CPU 比率的内存密集型工作负载，我们建议使用此 Worker 类型。
+ **R.4X** – 当您选择这种类型时，您还提供了 **Number of workers (工件数量)** 的值。每个 Worker 映射到 4 个 DPU（配置经过内存优化）。对于经常遇到内存不足错误或需要高内存与 CPU 比率的大型内存密集型工作负载，我们建议使用此 Worker 类型。
+ **R.8X** – 当您选择这种类型时，您还提供了 **Number of workers (工件数量)** 的值。每个 Worker 映射到 8 个 DPU（配置经过内存优化）。对于经常遇到内存不足错误或需要高内存与 CPU 比率的极大内存密集型工作负载，我们建议使用此 Worker 类型。
**Worker 类型规格**  
下表提供所有可用 G Worker 类型的详细规格：    
**G Worker 类型规格**    
<a name="table-worker-specifications"></a>[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/glue/latest/dg/add-job.html)
**重要提示：**G.12X 和 G.16X Worker 类型以及所有 R Worker 类型（R.1X 到 R.8X）均有较高的启动延迟。  
您将根据用于运行 ETL 作业的 DPU 数量按小时支付费用。有关更多信息，请参阅 [AWS Glue 价格页面](https://aws.amazon.com/glue/pricing/)。  
对于 AWS Glue 版本 1.0 或更低版本的任务，当您使用控制台配置任务并指定 **Standard (标准)** 的 **Worker type (工件类型)** 时，则会设置 **Maximum capacity (最大容量)**，并且 **Number of workers (工件数量)** 会成为 **Maximum capacity (最大容量)** 值 - 1。如果您使用 AWS Command Line Interface（AWS CLI）或 AWS SDK，则您可以指定 **Maximum capacity (最大容量)** 参数，也可以同时指定 **Worker type (工件类型)** 和 **Number of workers (工件数量)**。  
对于 AWS Glue 2.0 版或更高版本的作业，则不能指定**最大容量**。相反，您应该指定 **Worker type (工件类型)** 和 **Number of workers (工件数量)**。  
**G.4X** 和 **G.8X** 工作线程类型仅适用于以下 AWS 区域的 AWS Glue 3.0 或更高版本 Spark ETL 作业：美国东部（俄亥俄州）、美国东部（弗吉尼亚州北部）、美国西部（北加利福尼亚州）、美国西部（俄勒冈州）、亚太地区（孟买）、亚太地区（首尔）、亚太地区（新加坡）、亚太地区（悉尼）、亚太地区（东京）、加拿大（中部）、欧洲地区（法兰克福）、欧洲地区（爱尔兰）、欧洲地区（伦敦）、欧洲（西班牙）、欧洲地区（斯德哥尔摩）和南美洲（圣保罗）。  
**G.12X**、**G.16X** 以及 **R.1X** 至 **R.8X** Worker 类型仅适用于 AWS Glue 4.0 及更高版本的 Spark ETL 作业，且仅在以下 AWS 区域可用：美国东部（弗吉尼亚州北部）、美国西部（俄勒冈州）、美国东部（俄亥俄州）、欧洲地区（爱尔兰）和欧洲地区（法兰克福）。未来版本将支持更多区域。

**请求的工作线程数量**  
对于大多数工作线程类型，您必须指定作业运行时分配的工作线程数。

**作业书签**  
指定当作业运行时，AWS Glue 如何处理状态信息。您可以让它记住之前处理过的数据、更新状态信息或忽略状态信息。有关更多信息，请参阅 [使用作业书签跟踪已处理的数据](monitor-continuations.md)。

**作业运行排队**  
指定作业由于服务配额的原因而无法立即运行时，作业运行是否排队以便稍后运行。  
选中此选项后，将为作业运行启用作业运行排队。如果未填充任何选项，则不会考虑启用作业运行排队。  
如果此设置与作业运行中设置的值不匹配，则将使用作业运行字段中的值。

**Flex 执行**  
使用 AWS Studio 或 API 配置任务时，您可以指定标准或灵活的任务执行类。您的任务可能具有不同程度的优先级和时间敏感度。标准执行类非常适合需要快速任务启动和专用资源的时间敏感型工作负载。  
灵活的执行类适用于非紧急任务，例如预生产任务、测试和一次性数据加载。使用 AWS Glue 版本 3.0 或更高版本以及 `G.1X` 或 `G.2X` 工作线程类型的任务支持灵活的任务运行。新的 Worker 类型（`G.12X`、`G.16X` 以及 `R.1X` 至 `R.8X`）不支持灵活执行。  

[![AWS Videos](http://img.youtube.com/vi/https://www.youtube.com/embed/FnHCoTuDLXU/0.jpg)](http://www.youtube.com/watch?v=https://www.youtube.com/embed/FnHCoTuDLXU)

灵活的任务运行基于在任何时间点运行的工作线程数量计费。对于正在运行的灵活任务运行，可以添加或移除工作线程数。每个工作线程将贡献它在任务运行期间所运行的时间，而不是计费为 `Max Capacity` \$1 `Execution Time` 的简单计算。账单是（`Number of DPUs per worker` \$1 `time each worker ran`）的总和。  
有关更多信息，请参阅 AWS Studio 或 [作业](aws-glue-api-jobs-job.md) 和 [任务运行](aws-glue-api-jobs-runs.md) 中的帮助面板。

**重试次数**  
指定 AWS Glue 在失败时自动重新启动任务的次数（从 0 到 10）。达到超时限制的任务不会重新启动。

**作业超时**  
设置最大执行时间 (以分钟为单位)。最大执行时间为 7 天或 10080 分钟。否则，作业会引发异常。  
该值留空时，超时值默认为 2880 分钟。  
任何超时值大于 7 天的现有 AWS Glue 作业，该值默认为 7 天。例如，若为批处理作业指定了 20 天的超时值，则该作业会在第 7 天停止。  
**有关作业超时的最佳实践**  
作业按执行时间计费。为避免产生意外收费，请配置与作业的预期执行时间相适应的超时值。

**高级属性**    
**脚本文件名**  
作业的唯一脚本名称。不能命名为 **Untitled job**。  
**脚本路径**  
脚本的 Amazon S3 位置。路径必须采用 `s3://bucket/prefix/path/` 格式。它必须以斜杠（`/`）结尾，并且不包含任何文件。  
**作业指标**  
在运行此任务时，启用或禁用 Amazon CloudWatch 指标的创建。要查看分析数据，则必须启用此选项。有关如何启用和可视化指标的更多信息，请参阅 [作业监控和调试](monitor-profile-glue-job-cloudwatch-metrics.md)。  
**作业可观测性指标**  
在此作业运行时开启额外的 CloudWatch 可观测性指标的创建。有关更多信息，请参阅 [使用 AWS Glue 可观测性指标进行监控](monitor-observability.md)。  
**连续日志记录**  
启用对 Amazon CloudWatch 的持续日志记录。如果未启用此选项，则只有在作业完成后日志才可用。有关更多信息，请参阅 [AWS Glue 作业的日志记录](monitor-continuous-logging.md)。  
**Spark UI**  
允许使用 Spark UI 监控此任务。有关更多信息，请参阅 [为 AWS Glue 作业启用 Apache Spark Web UI](monitor-spark-ui-jobs.md)。  
**Spark UI 日志路径**  
启用 Spark UI 时写入日志的路径。  
**Spark UI 日志记录和监控配置**  
请选择以下选项之一：  
+ *标准*：使用 AWS Glue 作业运行 ID 作为文件名写入日志。在 AWS Glue 控制台中打开 Spark UI 监控。
+ *旧版*：使用“spark-application-\$1timestamp\$1”作为文件名写入日志。不打开 Spark UI 监控。
+ *标准和旧版*：将日志写入标准位置和旧版位置。在 AWS Glue 控制台中打开 Spark UI 监控。  
**最大并发数**  
设置此作业允许的并发运行的最大数量。默认 为 1。达到此阈值时，将返回一个错误。可以指定的最大值由服务限制控制。例如，如果在启动新实例时，作业的前一运行仍在运行，则可能需要返回错误以防止同一作业的两个实例同时运行。  
**临时路径**  
在 Amazon S3 中提供工作目录的位置，以便当 AWS Glue 运行脚本时在该位置写入临时中间结果。确认没有与路径中的临时目录同名的文件。在 AWS Glue 读取和写入 Amazon Redshift 时使用此目录，或者通过某些 AWS Glue 转换使用。  
如果区域中尚不存在存储桶，则 AWS Glue 会为任务创建临时存储桶。此存储桶可能允许公开访问。您可以修改 Amazon S3 中的存储桶以设置公开访问数据块，也可以在该区域中的所有任务完成之后删除存储桶。  
**延迟通知阈值（分钟）**  
设置发送延迟通知之前的阈值（以分钟为单位）。您可以设置此阈值，以在 `RUNNING`、`STARTING` 或 `STOPPING` 任务运行超过预期的分钟数时发送通知。  
**安全配置**  
从列表中选择安全配置。安全配置会指定如何对 Amazon S3 目标上的数据加密：不加密、使用 AWS KMS 托管式密钥的服务器端加密（SSE-KMS）或者使用 Amazon S3 托管式加密密钥的服务器端加密（SSE-S3）。  
**服务器端加密**  
如果选择此选项，在将 ETL 任务写入 Amazon S3 时，数据将会使用 SSE-S3 加密进行静态加密。Amazon S3 数据目标和任何写入 Amazon S3 临时目录的数据都将被加密。此选项作为作业参数传递。有关更多信息，请参阅 *Amazon Simple Storage Service 用户指南*中的[借助使用 Amazon S3 托管式加密密钥的服务器端加密 (SSE-S3) 保护数据](https://docs.aws.amazon.com/AmazonS3/latest/userguide/UsingServerSideEncryption.html)。  
如果指定了安全配置，则忽略此选项。  
**使用 Glue 数据目录作为 Hive 元存储**  
选择此项以使用 AWS Glue 数据目录作为 Hive 元存储。用于任务的 IAM 角色必须具有 `glue:CreateDatabase` 权限。在数据目录中创建一个名为“default”的数据库（如果该数据库不存在）。

**Connections**  
选择一个 VPC 配置来访问位于您的虚拟私有云（VPC）中的 Amazon S3 数据来源。您可以在 AWS Glue 中创建和管理网络连接。有关更多信息，请参阅 [连接到数据](glue-connections.md)。

**库**    
**Python 库路径、从属 JAR 路径和参考文件路径**  
如果脚本需要这些选项，请指定。当您定义任务时，可以为这些选项定义使用逗号分隔的 Amazon S3 路径。当您运行任务时，可以覆盖这些路径。有关更多信息，请参阅 [提供您自己的自定义脚本](console-custom-created.md)。  
**任务参数**  
作为命名参数传递给脚本的一组键值对。这些是在运行脚本时使用的默认值，但您可以在触发器中或运行任务时覆盖它们。您必须为键名使用前缀 `--`；例如：`--myKey`。使用 AWS Command Line Interface 时，您可以将任务参数作为映射传递。  
有关示例，请参阅 [在 AWS Glue 中传递和访问 Python 参数](aws-glue-programming-python-calling.md#aws-glue-programming-python-calling-parameters) 中的 Python 参数。  
**标签**  
使用 **Tag key (标签键)** 和可选的 **Tag value (标签值)** 来标记作业。创建标签键后，它们是只读的。对某些资源使用标签可帮助您整理和标识资源。有关更多信息，请参阅 [AWS Glue 中的 AWS 标签](monitor-tags.md)。

## 针对访问 Lake Formation 托管表的作业的限制
<a name="lf-table-restrictions"></a>

在创建针对由 AWS Lake Formation 托管的表进行读取或写入的任务时，请记住以下注意事项和限制：
+ 使用单元格级筛选条件访问表的任务中，不支持以下功能：
  + [任务书签](https://docs.aws.amazon.com/glue/latest/dg/monitor-continuations.html)和[有界执行](https://docs.aws.amazon.com/glue/latest/dg/bounded-execution.html)
  + [下推谓词](https://docs.aws.amazon.com/glue/latest/dg/aws-glue-programming-etl-partitions.html#aws-glue-programming-etl-partitions-pushdowns)
  + [服务器端目录分区谓词](https://docs.aws.amazon.com/glue/latest/dg/aws-glue-programming-etl-partitions.html#aws-glue-programming-etl-partitions-cat-predicates)
  + [enableUpdateCatalog](https://docs.aws.amazon.com/glue/latest/dg/update-from-job.html)

# 在 AWS Glue 控制台中编辑 Spark 脚本
<a name="edit-script-spark"></a>

脚本包含从源中提取数据、转换数据并将数据加载到目标中的代码。AWS Glue 在启动作业时运行脚本。

AWS Glue ETL 脚本可使用 Python 或 Scala 编码。Python 脚本使用 PySpark Python 方言的扩展语言来运行提取、转换和加载 (ETL) 作业。脚本包含*扩展构造*，用于处理 ETL 转换。当您为作业自动生成源代码逻辑时，会创建脚本。您可以编辑此脚本，也可以提供自己的脚本来处理您的 ETL 作业。

 有关如何在 AWS Glue 中定义和编辑脚本的信息，请参阅 [AWS Glue 编程指南](edit-script.md)。

## 其他库或文件
<a name="w2aac37c11c12c13b9"></a>

如果您的脚本需要额外的库或文件，您可以指定它们，如下所示：

**Python 库路径**  
以逗号分隔的到脚本所需的 Python 库的 Amazon Simple Storage Service（Amazon S3）路径。  
只能使用纯 Python 库。尚不支持依赖于 C 扩展的库，如 pandas Python 数据分析库。

**从属 jars 路径**  
脚本所需的以逗号分隔的到 JAR 文件的 Amazon S3 路径。  
目前，只能使用纯 Java 或 Scala (2.11) 库。

**引用的文件路径**  
以逗号分隔的到脚本所需的其他文件（例如，配置文件）的 Amazon S3 路径。

# 作业（旧版）
<a name="console-edit-script"></a>

脚本中包含用于执行提取、转换和加载 (ETL) 工作的代码。您可以提供您自己的脚本，或者 AWS Glue 可以通过您的指导生成脚本。有关创建您自己的脚本的信息，请参阅[提供您自己的自定义脚本](console-custom-created.md)。

您可以在 AWS Glue 控制台中编辑脚本。当您编辑脚本时，您可以添加源、目标和转换。

**编辑脚本**

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

1. 在列表中选择一个作业，然后选择 **Action**、**Edit script** 以打开脚本编辑器。

   您还可以从任务详细信息页面访问脚本编辑器。选择 **Script (脚本)** 选项卡，然后选择 **Edit script (编辑脚本)**。

   

## 脚本编辑器
<a name="console-edit-script-editor"></a>

利用 AWS Glue 脚本编辑器，您可以在脚本中插入、修改和删除源、目标和转换。脚本编辑器显示脚本和图表，可以帮助您直观呈现数据流。

要为脚本创建图表，请选择 **Generate diagram (生成示意图)**。AWS Glue 使用脚本中以 **\$1\$1** 开头的注释行来呈现示意图。要在图表中正确地表示脚本，必须将注释中的参数和 Apache Spark 代码中的参数保持同步。

脚本编辑器允许您在脚本中定位光标的任何位置添加代码模板。在编辑器的顶部，选择以下选项：
+ 要向脚本中添加源表，请选择 **Source**。
+ 要向脚本中添加目标表，请选择 **Target**。
+ 要向脚本中添加目标位置，请选择 **Target location**。
+ 要向脚本中添加转换，请选择 **Transform**。有关脚本中调用的函数的信息，请参阅[在 PySpark 中编写 AWS Glue ETL 脚本](aws-glue-programming-python.md)。
+ 要向脚本中添加 Spigot，请选择 **Spigot**。

在插入的代码中，修改注释和 Apache Spark 代码中的 `parameters`。例如，如果您添加 **Spigot** 转换，请验证 `path` 在 `@args` 注释行和 `output` 代码行中都被替换。

**Logs** 选项卡显示在作业运行时与其关联的日志。将会显示最新的 1000 行。

**Schema (架构)** 选项卡显示选定源和目标的架构（在数据目录中可用时）。

# 使用作业书签跟踪已处理的数据
<a name="monitor-continuations"></a>

AWS Glue 通过保存作业运行的状态信息来跟踪上次运行 ETL 作业期间已处理的数据。此持久状态信息称为*作业书签*。作业书签可帮助 AWS Glue 维护状态信息，并可防止重新处理旧数据。有了作业书签，您可以在按照计划的时间间隔重新运行时处理新数据。作业书签包含作业的各种元素的状态，如源、转换和目标。例如，您的 ETL 任务可能会读取 Amazon S3 文件中的新分区。AWS Glue 跟踪任务已成功处理哪些分区，以防止任务的目标数据存储中出现重复处理和重复数据。

为 JDBC 数据源、关系化转换和一些 Amazon Simple Storage Service（Amazon S3）源实施了任务书签。下表列出了 AWS Glue 支持任务书签的 Amazon S3 源格式。


| AWS Glue 版本 | Amazon S3 源格式 | 
| --- | --- | 
| 版本 0.9 | JSON、CSV、Apache Avro、XML | 
| 版本 1.0 及更高版本 | JSON、CSV、Apache Avro、XML、Parquet、ORC | 

有关 AWS Glue 版本的信息，请参阅[定义 Spark 作业的作业属性](add-job.md#create-job)。

通过 AWS Glue 脚本访问作业书签功能时，还具有其他功能。浏览生成的脚本时，您可能会看到与此功能相关的转换上下文。有关更多信息，请参阅 [使用作业书签](programming-etl-connect-bookmarks.md)。

**Topics**
+ [在 AWS Glue 中使用作业书签](#monitor-continuations-implement)
+ [作业书签功能的操作详细信息](#monitor-continuations-script)

## 在 AWS Glue 中使用作业书签
<a name="monitor-continuations-implement"></a>

在启动作业时，作业书签选项作为参数传递。下表描述了在 AWS Glue 控制台中用于设置任务书签的选项。


****  

| 作业书签 | 描述 | 
| --- | --- | 
| Enable | 使作业在运行后更新状态，以跟踪之前处理的数据。如果作业的源支持作业书签，它将跟踪已处理的数据，当作业运行时，它将处理自上一检查点以来的新数据。 | 
| 禁用 | 不使用作业书签，作业始终处理整个数据集。您负责管理上一个作业运行的输出。这是默认值。 | 
| Pause |  处理上次成功运行以来的增量数据或以下子选项标识的范围内的数据，无需更新最后一个书签的状态。您负责管理上一个作业运行的输出。这两个子选项是： [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/glue/latest/dg/monitor-continuations.html) 指定此选项集时，作业书签状态不更新。 子选项是可选的，但是使用时，需要提供两个子选项。  | 

有关命令行上传递给作业的参数的详细信息（特别是关于作业书签的详细信息），请参阅[在 AWS Glue 作业中使用作业参数](aws-glue-programming-etl-glue-arguments.md)。

对于 Amazon S3 输入源，AWS Glue 任务书签将通过检查对象的上次修改时间来验证哪些对象需要重新处理。如果您的输入源数据在上次作业运行后已修改，则再次运行作业时将重新处理这些文件。

对于 JDBC 源，以下规则将适用：
+ 对于每个表，AWS Glue 使用一个或多个列作为书签键来确定新数据和处理过的数据。书签键将合并成一个复合键。
+ AWS Glue 默认情况下将使用主键作为书签键，前提是它按顺序递增或递减（没有间隙）。
+ 可以指定要用作 AWS Glue 脚本中书签键的列。有关在 AWS Glue 脚本模式中使用作业书签的更多信息，请参阅 [使用作业书签](programming-etl-connect-bookmarks.md)。
+ AWS Glue 不支持使用区分大小写的列作为作业书签键。

您可以将您的 AWS Glue Spark ETL 任务的任务书签倒回之前的任何任务运行。您可以通过将您的作业书签倒回之前的任何作业运行来更好的支持数据回填场景，从而使后续作业运行只再处理已做上标签的作业运行的数据。

如果您打算使用相同的作业重新处理所有数据，请重置作业书签。要重置作业书签状态，请使用 AWS Glue 控制台、[ResetJobBookmark 操作（Python：reset\$1job\$1bookmark）](aws-glue-api-jobs-runs.md#aws-glue-api-jobs-runs-ResetJobBookmark) API 操作或 AWS CLI。例如，使用 AWS CLI 输入以下命令：

```
    aws glue reset-job-bookmark --job-name my-job-name
```

在回放或重置书签时，AWS Glue 不会清除目标文件，因为可能有多个目标，并且不会使用任务书签跟踪目标。仅使用任务书签跟踪源文件。在回卷和重新处理源文件时，您可以创建不同的输出目标，以避免输出中出现重复数据。

AWS Glue 按作业跟踪作业书签。如果您删除作业，作业书签也会被删除。

有些情况下，您可能已启用 AWS Glue 作业书签，但您的 ETL 作业还在重新处理早期运行中已处理的数据。有关解决该错误的常见原因的信息，请参阅[Glue 常见设置错误故障排除](glue-troubleshooting-errors.md)。

## 作业书签功能的操作详细信息
<a name="monitor-continuations-script"></a>

本节将介绍有关使用作业书签的更多操作详情。

作业书签存储作业的状态。每个状态实例的键由作业名称和版本号组成。当脚本调用 `job.init` 时，它将检索其状态并始终获取最新版本。在一个状态中，有多个状态元素，这些元素特定于脚本中的每个源、转换和接收器实例。这些状态元素由附加至脚本中相应元素（源、转换或接收器）的转换上下文来标识。从用户脚本中调用 `job.commit` 时，将自动保存状态元素。脚本将从参数中获取作业书签的作业名称和控制选项。

作业书签中的状态元素是特定于源、转换或接收器的数据。例如，假设您要从上游任务或进程不断写入数据的 Amazon S3 位置读取增量数据。在这种情况下，脚本必须确定目前已处理的内容。Amazon S3 源的任务书签实现将保存信息，这样，当任务再次运行时，它可以使用保存的信息仅筛选新对象并重新计算任务的下次运行状态。时间戳用于筛选新文件。

除了状态元素外，作业书签还有*运行编号*、*尝试次数* 和*版本号*。运行编号跟踪作业的运行，尝试次数记录作业运行的尝试次数。作业运行编号是随着每次成功运行单调增加的数字。尝试次数跟踪每次运行的尝试，仅在失败尝试后有运行时才增加。版本号单调增加并跟踪作业书签的更新。

在 AWS Glue 服务数据库中，所有转换的书签状态都作为键值对存储在一起：

```
{
  "job_name" : ...,
  "run_id": ...,
  "run_number": ..,
  "attempt_number": ...
  "states": {
    "transformation_ctx1" : {
      bookmark_state1
    },
    "transformation_ctx2" : {
      bookmark_state2
    }
  }
}
```

**最佳实践**  
以下是使用作业书签的最佳实践。
+ *请勿在启用书签的情况下更改数据源属性*。例如，假定 datasource0 指向 Simple Storage Service (Amazon S3) 输入路径 A，并且该任务从启用书签情况下运行数轮的源进行读取。如果您将 datasource0 的输入路径更改为 Simple Storage Service (Amazon S3) 路径 B 而未更改 `transformation_ctx`，则 AWS Glue 任务将使用存储的旧书签状态。这将导致丢失或跳过输入路径 B 中的文件，因为 AWS Glue 将假定这些文件在以前的运行中已经处理过。
+ *将目录表和书签搭配使用以实现更好的分区管理*。书签既适用于来自数据目录的数据源，也适用于来自选项的数据源。但是，使用来自选项方法很难删除/添加新的分区。将目录表和爬网程序搭配使用可以提供更好的自动化，以跟踪新添加的[分区](https://docs.aws.amazon.com/glue/latest/dg/tables-described.html#tables-partition)并让您通过[下推谓词](https://docs.aws.amazon.com/glue/latest/dg/aws-glue-programming-etl-partitions.html)灵活选择特定的分区。
+ *使用适合大型数据集的 [AWS Glue Simple Storage Service (Amazon S3 文件列表器](https://aws.amazon.com/premiumsupport/knowledge-center/glue-oom-java-heap-space-error/)*。书签将列出每个输入分区下的所有文件并进行筛选，因此，如果单个分区下的文件过多，书签可以运行到驱动程序 OOM 中。使用 AWS Glue Simple Storage Service (Amazon S3) 文件列表器，以避免一次在内存中列出所有文件。

# 存储 Spark 随机排序数据
<a name="monitor-spark-shuffle-manager"></a>

每当数据在分区之间重新排列时，随机排序是 Spark 任务中的一个重要步骤。这是必需的，因为 `join`、` groupByKey`、`reduceByKey` 和 `repartition` 等广泛的转换需要来自其他分区的信息才能完成处理。Spark 从每个分区收集所需的数据，并将其合并到一个新的分区中。在随机排序过程中，数据会写入磁盘并通过网络传输。因此，随机排序操作绑定到本地磁盘容量。当执行程序上没有足够的磁盘空间并且没有恢复时，Spark 会抛出一个 `No space left on device` 或 ` MetadataFetchFailedException` 错误。

**注意**  
 Amazon S3 中的 AWS Glue Spark Shuffle Plugin 仅支持 AWS Glue ETL 作业。

**解决方案**  
通过 AWS Glue，您现在可以使用 Amazon S3 存储 Spark Shuffle 数据。Amazon S3 是一种对象存储服务，提供行业领先的可扩展性、数据可用性、安全性和性能。此解决方案可分解 Spark 任务的计算和存储，并提供完整的弹性和低成本的随机排序存储，使您能够可靠地运行随机排序最密集的工作负载。

![\[Spark workflow showing Map and Reduce stages using Amazon S3 for shuffle data storage.\]](http://docs.aws.amazon.com/zh_cn/glue/latest/dg/images/gs-s3-shuffle-diagram.png)


我们即将推出适用于 Apache Spark 的 Cloud Shuffle Storage 插件，以使用 Amazon S3。如果已知任务受大规模随机排序操作的本地磁盘容量限制，则可以启用 Amazon S3 随机排序来可靠、无故障地运行 AWS Glue 任务。在某些情况下，如果您有大量的小分区或随机排序文件写入 Amazon S3，则随机排序到 Amazon S3 的速度比本地磁盘（或 EBS）慢一些。

## 使用 Cloud Shuffle Storage Plugin 的先决条件
<a name="monitor-spark-shuffle-manager-prereqs"></a>

 要将 Cloud Shuffle Storage Plugin 用于 AWS Glue ETL 作业，需要满足以下条件：
+ 与您的作业运行位于同一区域的 Amazon S3 存储桶，用于存储随机排序和溢出的数据。可使用 `--conf spark.shuffle.glue.s3ShuffleBucket=s3://shuffle-bucket/prefix/` 指定随机排序存储的 Amazon S3 前缀，如以下示例所示：

  ```
  --conf spark.shuffle.glue.s3ShuffleBucket=s3://glue-shuffle-123456789-us-east-1/glue-shuffle-data/
  ```
+  在*前缀*上设置 Amazon S3 存储生命周期策略（例如 `glue-shuffle-data`），因为作业完成后，随机排序管理器不会清理文件。作业完成后，应删除中间随机排序和溢出的数据。用户可以在前缀上设置短生命周期策略。有关设置 Amazon S3 生命周期策略的说明，请参阅《 Amazon Simple Storage Service 用户指南》中的 [Setting lifecycle configuration on a bucket](https://docs.aws.amazon.com//AmazonS3/latest/userguide/how-to-set-lifecycle-configuration-intro.html)。

## 从 AWS 控制台使用 AWS Glue Spark 随机排序管理器
<a name="monitor-spark-shuffle-manager-using-console"></a>

在配置作业时使用 AWS Glue 控制台或 AWS Glue Studio 设置 AWS Glue Spark 随机排序管理器：选择 ** --write-shuffle-files-to-s3** 作业参数启用作业的 Amazon S3 随机排序。

![\[Job parameters interface showing --write-shuffle-files- parameter and option to add more.\]](http://docs.aws.amazon.com/zh_cn/glue/latest/dg/images/gs-s3-shuffle.png)


## 使用 AWS Glue Spark Shuffle 插件
<a name="monitor-spark-shuffle-manager-using"></a>

以下任务参数启用并调整 AWS Glue 随机排序管理器。这些参数是标志，因此不考虑所提供的任何值。
+ `--write-shuffle-files-to-s3` – 主标志，启用 AWS Glue Spark 随机排序管理器，以使用 Amazon S3 存储桶写入和读取随机排序数据。如果标志未指定，则不使用随机排序管理器。
+ `--write-shuffle-spills-to-s3`—（仅在 AWS Glue 版本 2.0 上支持）。一个可选标志，允许您将溢出文件卸载到 Amazon S3 存储桶，从而为您的 Spark 作业提供额外的弹性。只有将大量数据溢出到磁盘的大型工作负载才需要这样做。如果未指定该标志，则不会写入任何中间溢出文件。
+ ` --conf spark.shuffle.glue.s3ShuffleBucket=s3://<shuffle-bucket>` – 另一个可选标志，用于指定您在其中写入随机排序文件的 Amazon S3 存储桶。默认情况下，`--TempDir`/shuffle-data. AWS Glue 3.0\$1 支持通过使用逗号分隔符指定存储桶，将随机排序文件写入多个存储桶，如 `--conf spark.shuffle.glue.s3ShuffleBucket=s3://shuffle-bucket-1/prefix,s3://shuffle-bucket-2/prefix/` 中所示。使用多个存储桶可以提高性能。

您需要提供安全配置设置，才能对随机排序数据启用静态加密。有关安全配置的更多信息，请参阅 [在 AWS Glue 中设置加密](set-up-encryption.md)。AWS Glue 支持 Spark 提供的所有其他随机排序相关配置。

**Cloud Shuffle Storage 插件的软件二进制文件**  
您还可以在 Apache 2.0 许可证下下载适用于 Apache Spark 的 Cloud Shuffle Storage 插件的软件二进制文件，然后在任何 Spark 环境中运行它。新插件对 Amazon S3 提供开箱即用支持，也可以轻松配置为使用其他形式的云存储，例如 [Google Cloud Storage 和 Microsoft Azure Blob Storage](https://github.com/aws-samples/aws-glue-samples/blob/master/docs/cloud-shuffle-plugin/README.md)。有关更多信息，请参阅[适用于 Apache Spark 的 Cloud Shuffle Storage 插件](https://docs.aws.amazon.com/glue/latest/dg/cloud-shuffle-storage-plugin.html)。

**注释和限制**  
以下是 AWS Glue 随机排序管理器的注释或限制：
+  作业完成后，AWS Glue 随机排序管理器不会自动删除存储在 Amazon S3 存储桶中的（临时）随机排序数据文件。为确保数据保护，请在启用 Cloud Shuffle Storage Plugin 之前按照 [使用 Cloud Shuffle Storage Plugin 的先决条件](#monitor-spark-shuffle-manager-prereqs) 中的说明进行操作。
+ 如果数据出现误差，则可以使用此功能。

# 适用于 Apache Spark 的 Cloud Shuffle 存储插件
<a name="cloud-shuffle-storage-plugin"></a>

Cloud Shuffle 存储插件是一款与 [`ShuffleDataIO` API](https://github.com/apache/spark/blob/master/core/src/main/java/org/apache/spark/shuffle/api/ShuffleDataIO.java) 兼容的 Apache Spark 插件，它允许在云存储系统（例如 Amazon S3）上存储 shuffle 数据。它可以帮助您补充或替换本地磁盘存储容量以进行大型随机播放，这些操作通常由 Spark 应用程序中的 `join`、`reduceByKey`、`groupByKey` 和 `repartition` 等转换触发，从而减少无服务器数据分析任务和管道的常见故障或性价比/性能失调。

**AWS Glue**  
AWS Glue 版本 3.0 和 4.0 预装了插件，无需任何额外步骤即可在 Amazon S3 上进行重组。有关更多信息，请参阅 [AWS Glue 搭载 Amazon S3 的 Spark shuffle 插件](https://docs.aws.amazon.com/glue/latest/dg/monitor-spark-shuffle-manager.html)，以为您的 Spark 应用程序启用该功能。

**其他 Spark 环境**  
该插件要求在其他 Spark 环境中设置以下 Spark 配置：
+ `--conf spark.shuffle.sort.io.plugin.class=com.amazonaws.spark.shuffle.io.cloud.ChopperPlugin`：这通知 Spark 为 Shuffle IO 使用这个插件。
+ `--conf spark.shuffle.storage.path=s3://bucket-name/shuffle-file-dir`：您的随机播放文件的存储路径。

**注意**  
该插件覆盖了一个 Spark 核心类。因此，需要在 Spark jar 之前加载插件 jar。如果在 AWS Glue 外部使用插件，则可以使用 `userClassPathFirst` 在本地 YARN 环境中执行此操作。

## 将插件与您的 Spark 应用程序捆绑在一起
<a name="cloud-shuffle-storage-plugin-bundling"></a>

在本地开发 Spark 应用程序时，您可以在 Maven `pom.xml` 中添加插件依赖关系，将插件与 Spark 应用程序和 Spark 发行版（版本 3.1 及更高版本）捆绑在一起。有关插件和 Spark 版本的更多信息，请参阅[插件版本](#cloud-shuffle-storage-plugin-versions)。

```
<repositories>
   ...
    <repository>
        <id>aws-glue-etl-artifacts</id>
        <url>https://aws-glue-etl-artifacts.s3.amazonaws.com/release/ </url>
    </repository>
</repositories>
...
<dependency>
    <groupId>com.amazonaws</groupId>
    <artifactId>chopper-plugin</artifactId>
    <version>3.1-amzn-LATEST</version>
</dependency>
```

您也可以直接从 AWS Glue Maven 构件下载二进制文件，并将它们包含在您的 Spark 应用程序中，如下所示。

```
#!/bin/bash
sudo wget -v https://aws-glue-etl-artifacts.s3.amazonaws.com/release/com/amazonaws/chopper-plugin/3.1-amzn-LATEST/chopper-plugin-3.1-amzn-LATEST.jar -P /usr/lib/spark/jars/
```

Spark 提交示例

```
spark-submit --deploy-mode cluster \
--conf spark.shuffle.storage.s3.path=s3://<ShuffleBucket>/<shuffle-dir> \
--conf spark.driver.extraClassPath=<Path to plugin jar> \ 
--conf spark.executor.extraClassPath=<Path to plugin jar> \
--class <your test class name> s3://<ShuffleBucket>/<Your application jar> \
```

## 可选配置
<a name="cloud-shuffle-storage-plugin-optional"></a>

这些是控制 Amazon S3 随机播放行为的可选配置。
+ `spark.shuffle.storage.s3.enableServerSideEncryption`：为随机播放和溢出文件启用/禁用 S3 SSE。默认值为 `true`。
+ `spark.shuffle.storage.s3.serverSideEncryption.algorithm`：要使用的 SSE 算法。默认值为 `AES256`。
+ `spark.shuffle.storage.s3.serverSideEncryption.kms.key`：启用 SSE aws:kms 时的 KMS 密钥 ARN。

除了这些配置之外，您可能还需要设置配置（例如 `spark.hadoop.fs.s3.enableServerSideEncryption` 和**其他特定于环境的配置**），以确保为您的用例应用适当的加密。

## 插件版本
<a name="cloud-shuffle-storage-plugin-versions"></a>

与每个 AWS Glue 版本关联的 Spark 版本都支持此插件。下表显示了插件的软件二进制文件的 AWS Glue 版本、Spark 版本和关联的插件版本以及 Amazon S3 的位置。


| AWS Glue 版本 | Spark 版本 | 插件版本 | Amazon S3 位置 | 
| --- | --- | --- | --- | 
| 3.0 | 3.1 | 3.1-amzn-LATEST |  s3://aws-glue-etl-artifacts/release/com/amazonaws/chopper-plugin/3.1-amzn-0/chopper-plugin-3.1-amzn-LATEST.jar  | 
| 4.0 | 3.3 | 3.3-amzn-LATEST |  s3://aws-glue-etl-artifacts/release/com/amazonaws/chopper-plugin/3.3-amzn-0/chopper-plugin-3.3-amzn-LATEST.jar  | 

## 许可证
<a name="cloud-shuffle-storage-plugin-binary-license"></a>

此插件的软件二进制文件已根据 Apache-2.0 许可证获得许可。

# 监控 AWS Glue Spark 作业
<a name="monitor-spark"></a>

**Topics**
+ [AWS Glue Studio 中可用的 Spark 指标](#console-jobs-details-metrics-spark)
+ [使用 Apache Spark Web UI 监控作业](monitor-spark-ui.md)
+ [通过 AWS Glue 任务运行洞察进行监控](monitor-job-insights.md)
+ [使用 Amazon CloudWatch 监控](monitor-cloudwatch.md)
+ [作业监控和调试](monitor-profile-glue-job-cloudwatch-metrics.md)

## AWS Glue Studio 中可用的 Spark 指标
<a name="console-jobs-details-metrics-spark"></a>

**Metrics (指标)** 选项卡显示启用任务运行和分析时收集的指标。Spark 作业显示了以下图表：
+ ETL 数据移动
+ 内存配置文件：驱动程序和执行程序

选择 **View additional metrics (查看其他指标)** 显示以下图表：
+ ETL 数据移动
+ 内存配置文件：驱动程序和执行程序
+ 执行程序之间的数据随机排序
+ CPU 负载：驱动程序和执行程序
+ 作业执行：活动执行程序、已完成的阶段和需求最大的执行程序

如果已启用任务以收集指标，系统则会将这些图表的数据推送到 CloudWatch 指标。有关如何启用指标和解释图表的更多信息，请参阅[作业监控和调试](monitor-profile-glue-job-cloudwatch-metrics.md)。

**Example ETL 数据移动图表**  
ETL 数据移动图表会显示以下指标：  
+ 所有执行程序从 Amazon S3 读取的字节数 – [`glue.ALL.s3.filesystem.read_bytes`](monitoring-awsglue-with-cloudwatch-metrics.md#glue.ALL.s3.filesystem.read_bytes)
+ 所有执行程序写入 Amazon S3 的字节数 – [`glue.ALL.s3.filesystem.write_bytes`](monitoring-awsglue-with-cloudwatch-metrics.md#glue.ALL.s3.filesystem.write_bytes)

![\[AWS Glue 控制台的 Metrics (指标) 选项卡中显示 ETL 数据移动的图表。\]](http://docs.aws.amazon.com/zh_cn/glue/latest/dg/images/job_detailed_etl.png)


**Example 内存配置文件图表**  
内存配置文件图表会显示以下指标：  
+ 驱动程序的 JVM 堆用于此驱动程序的内存量（比例：0-1），用 *executorId* 标识的执行程序，或所有执行程序 –
  + [`glue.driver.jvm.heap.usage`](monitoring-awsglue-with-cloudwatch-metrics.md#glue.driver.jvm.heap.usage)
  + [`glue.executorId.jvm.heap.usage`](monitoring-awsglue-with-cloudwatch-metrics.md#glue.executorId.jvm.heap.usage)
  + [`glue.ALL.jvm.heap.usage`](monitoring-awsglue-with-cloudwatch-metrics.md#glue.ALL.jvm.heap.usage)

![\[AWS Glue 控制台的 Metrics (指标) 选项卡中显示内存配置文件的图表。\]](http://docs.aws.amazon.com/zh_cn/glue/latest/dg/images/job_detailed_mem.png)


**Example 执行程序之间的数据随机排序图表**  
执行程序之间的数据随机排序图表显示了以下指标：  
+ 所有执行程序用于在它们之间对数据进行随机排序所读取的字节数 -[`glue.driver.aggregate.shuffleLocalBytesRead`](monitoring-awsglue-with-cloudwatch-metrics.md#glue.driver.aggregate.shuffleLocalBytesRead)
+ 所有执行程序用于在它们之间对数据进行随机排序所写入的字节数 -[`glue.driver.aggregate.shuffleBytesWritten`](monitoring-awsglue-with-cloudwatch-metrics.md#glue.driver.aggregate.shuffleBytesWritten)

![\[AWS Glue 控制台的 Metrics (指标) 选项卡中显示执行程序之间的数据随机排序图表。\]](http://docs.aws.amazon.com/zh_cn/glue/latest/dg/images/job_detailed_data.png)


**Example CPU 负载图表**  
CPU 负载图表显示以下指标：  
+ 驱动程序使用的 CPU 系统负载量（比例：0-1），用 *executorId* 标识的执行程序，或所有执行程序 –
  + [`glue.driver.system.cpuSystemLoad`](monitoring-awsglue-with-cloudwatch-metrics.md#glue.driver.system.cpuSystemLoad)
  + [`glue.executorId.system.cpuSystemLoad`](monitoring-awsglue-with-cloudwatch-metrics.md#glue.executorId.system.cpuSystemLoad)
  + [`glue.ALL.system.cpuSystemLoad`](monitoring-awsglue-with-cloudwatch-metrics.md#glue.ALL.system.cpuSystemLoad)

![\[AWS Glue 控制台的 Metrics (指标) 选项卡中显示 CPU 负载的图表。\]](http://docs.aws.amazon.com/zh_cn/glue/latest/dg/images/job_detailed_cpu.png)


**Example 作业执行图表**  
作业执行图表显示以下指标：  
+ 主动运行的执行程序的数量 -[`glue.driver.ExecutorAllocationManager.executors.numberAllExecutors`](monitoring-awsglue-with-cloudwatch-metrics.md#glue.driver.ExecutorAllocationManager.executors.numberAllExecutors)
+ 已完成的阶段数量 -[`glue.aggregate.numCompletedStages`](monitoring-awsglue-with-cloudwatch-metrics.md#glue.driver.aggregate.numCompletedStages)
+ 需求最大的执行程序的数量 -[`glue.driver.ExecutorAllocationManager.executors.numberMaxNeededExecutors`](monitoring-awsglue-with-cloudwatch-metrics.md#glue.driver.ExecutorAllocationManager.executors.numberMaxNeededExecutors)

![\[AWS Glue 控制台的 Metrics (指标) 选项卡中显示任务执行的图表。\]](http://docs.aws.amazon.com/zh_cn/glue/latest/dg/images/job_detailed_exec.png)


# 使用 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。

# 通过 AWS Glue 任务运行洞察进行监控
<a name="monitor-job-insights"></a>

AWS Glue 任务运行洞察是 AWS Glue 中的一个功能，可为 AWS Glue 任务简化任务调试和进行优化。AWS Glue 可提供 [Spark UI](https://docs.aws.amazon.com/glue/latest/dg/monitor-spark-ui.html) 和 [CloudWatch 日志和指标](https://docs.aws.amazon.com/glue/latest/dg/monitor-cloudwatch.html)，以便监控您的 AWS Glue 任务。使用此功能，您可获得有关 AWS Glue 任务执行情况的信息：
+ 失败的 AWS Glue 任务脚本的行号。
+ 在您的作业失败之前，在 Spark 查询计划中最后执行的 Spark 操作。
+ 在按时间排序的日志流中显示与故障相关的 Spark 异常事件。
+ 根本原因分析和解决问题的建议措施（如优化脚本）。
+ 常见的 Spark 事件（与 Spark 操作有关的日志消息），其中包含解决根本原因的推荐操作。

使用 AWS Glue 任务的 CloudWatch 日志中的两个新日志流，您可以获得所有这些洞察。

## 要求
<a name="monitor-job-insights-requirements"></a>

AWS Glue 作业运行洞察功能可用于 AWS Glue 版本 2.0 及更高版本。您可以按照现有任务的[迁移指南](https://docs.aws.amazon.com/glue/latest/dg/migrating-version-30.html)从较早的 AWS Glue 版本进行升级。

## 为 AWS Glue ETL 作业启用任务运行洞察
<a name="monitor-job-insights-enable"></a>

您可以通过 AWS Glue Studio 或 CLI 启用任务运行洞察。

### AWS Glue Studio
<a name="monitor-job-insights-requirements"></a>

通过 AWS Glue Studio 创建任务时，您可以在 **Job Details**（任务详细信息）选项卡下启用或禁用任务运行洞察。确认**生成作业洞察**框是否处于选中状态。

![\[在 AWS Glue Studio 中启用任务运行洞察。\]](http://docs.aws.amazon.com/zh_cn/glue/latest/dg/images/monitor-job-run-insights-1.png)


### 命令行
<a name="monitor-job-insights-enable-cli"></a>

如果通过 CLI 创建任务，则可以通过简单的新 [job parameter](https://docs.aws.amazon.com/glue/latest/dg/aws-glue-programming-etl-glue-arguments.html)（任务参数）启动任务运行：`--enable-job-insights = true`。

默认情况下，任务运行洞察日志流在 [AWS Glue 连续录入](https://docs.aws.amazon.com/glue/latest/dg/monitor-continuous-logging.html)使用的同一个默认日志组下进行创建，也就是 `/aws-glue/jobs/logs-v2/`。您可以使用相同的参数集来设置自定义日志组名称、日志筛选条件和日志组配置以进行连续日志录入。有关更多信息，请参阅[启用 AWS Glue 任务的连续日志录入](https://docs.aws.amazon.com/glue/latest/dg/monitor-continuous-logging-enable.html)。

## 在 CloudWatch 中访问作业运行洞察日志流
<a name="monitor-job-insights-access"></a>

启用任务运行洞察功能后，任务运行失败时可能会创建两个日志流。当任务成功完成后，两个流都不会生成。

1. *异常分析日志流*：`<job-run-id>-job-insights-rca-driver`。该数据流提供以下功能：
   + 导致失败的 AWS Glue 任务脚本的行号。
   + Spark 查询计划 (DAG) 中最后执行的 Spark 操作。
   + 来自与异常相关的 Spark 驱动程序和执行器的简明时序事件。您可以找到详细信息，例如完整的错误消息、失败的 Spark 任务及其执行者 ID，这些信息可帮助您专注于特定执行者的日志流，以便在需要时进行更深入的调查。

1. *基于规则的洞察流式传输*：
   + 根本原因分析和如何修复错误的建议（例如使用特定的任务参数来优化性能）。
   + 作为根本原因分析的基础和建议的行动的相关 Spark 事件。

**注意**  
第一个流仅在任何异常触发事件可用于失败的任务运行时存在，第二个流仅在任何洞察可用于失败的任务运行时存在。例如，如果您的任务成功完成，则不会生成任何流；如果您的任务失败，但是没有服务定义的规则可以与您的失败场景匹配，那么将只生成第一个流。

如果通过 AWS Glue Studio 创建任务，则在“任务运行详细信息”选项卡（任务运行洞察）下，还可提供指向上述流式传输的链接，即“简明和综合错误日志”和“错误分析和指导”。

![\[包含日志流链接的任务运行详细信息页面。\]](http://docs.aws.amazon.com/zh_cn/glue/latest/dg/images/monitor-job-run-insights-2.png)


## AWS Glue 任务运行洞察的示例
<a name="monitor-job-insights-example"></a>

在本节中，我们将举例说明任务运行洞察功能如何帮助您解决失败任务中的问题。在本例中，用户忘记在用来分析和构建基于其数据的机器学习模型的 AWS Glue 任务中导入所需的模块 (tensorflow)。

```
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.types import *
from pyspark.sql.functions import udf,col

args = getResolvedOptions(sys.argv, ['JOB_NAME'])

sc = SparkContext()
glueContext = GlueContext(sc)
spark = glueContext.spark_session
job = Job(glueContext)
job.init(args['JOB_NAME'], args)

data_set_1 = [1, 2, 3, 4]
data_set_2 = [5, 6, 7, 8]

scoresDf = spark.createDataFrame(data_set_1, IntegerType())

def data_multiplier_func(factor, data_vector):
    import tensorflow as tf
    with tf.compat.v1.Session() as sess:
        x1 = tf.constant(factor)
        x2 = tf.constant(data_vector)
        result = tf.multiply(x1, x2)
        return sess.run(result).tolist()

data_multiplier_udf = udf(lambda x:data_multiplier_func(x, data_set_2), ArrayType(IntegerType(),False))
factoredDf = scoresDf.withColumn("final_value", data_multiplier_udf(col("value")))
print(factoredDf.collect())
```

如果没有任务运行洞察功能，当任务失败时，您只会看到 Spark 抛出的以下消息:

`An error occurred while calling o111.collectToPython. Traceback (most recent call last):`

消息不明确，限制了您的调试体验。在这种情况下，此功能在两个 CloudWatch 日志流中为您提供了更多洞察：

1. `job-insights-rca-driver` 日志流：
   + *异常事件*：此日志流为您提供与从 Spark 驱动程序和不同分布式工作人员收集的故障相关的 Spark 异常事件。这些事件有助于您理解异常在错误代码跨 Spark 任务、执行器和分布在 AWS Glue 工作器中的阶段执行时的时间顺序传播。
   + *行号*：这个日志流标识了第 21 行，我们对此进行调用，以导入导致失败的缺失 Python 模块；它还将第 24 行（对 Spark 操作 `collect()` 的调用）标识为脚本中最后执行的一行。  
![\[job-insights-rca-driver 日志流。\]](http://docs.aws.amazon.com/zh_cn/glue/latest/dg/images/monitor-job-run-insights-3.png)

1. `job-insights-rule-driver` 日志流：
   + *根本原因和建议*：除了脚本中错误的行号和上次执行的行号之外，此日志流还显示了根本原因分析和建议，供您遵循 AWS Glue 文档并设置必要的任务参数，以便在 AWS Glue 任务中使用额外的 Python 模块。
   + *基础事件*：此日志流还显示了使用服务定义的规则评估的 Spark 异常事件，以推断根本原因并提供建议。  
![\[job-insights-rule-driver 日志流。\]](http://docs.aws.amazon.com/zh_cn/glue/latest/dg/images/monitor-job-run-insights-4.png)

# 使用 Amazon CloudWatch 监控
<a name="monitor-cloudwatch"></a>

您可以使用 Amazon CloudWatch 监控 AWS Glue，此工具可从 AWS Glue 收集原始数据，并将其处理为易读的近乎实时的指标。这些统计数据会保存两周，从而使您能够访问历史信息，以更好地了解您的 Web 应用程序或服务的执行情况。默认情况下，AWS Glue 指标数据自动发送到 CloudWatch。有关更多信息，请参阅《Amazon CloudWatch 用户指南》**中的[什么是 Amazon CloudWatch？](https://docs.aws.amazon.com/AmazonCloudWatch/latest/DeveloperGuide/WhatIsCloudWatch.html)和[AWS Glue 指标](monitoring-awsglue-with-cloudwatch-metrics.md#awsglue-metrics)。

 **持续日志记录** 

AWS Glue 还支持对 AWS Glue 作业的实时连续日志记录。为任务启用连续日志记录之后，您可在 AWS Glue 控制台或 CloudWatch 控制台控制面板上查看实时日志。有关更多信息，请参阅 [AWS Glue 作业的日志记录](monitor-continuous-logging.md)。

 **可观测性指标** 

 启用**作业可观测性指标**后，作业运行时将会生成额外的 Amazon CloudWatch 指标。使用 AWS Glue 可观测性指标可深入了解 AWS Glue 内部发生的情况，从而可以改进对问题的分类和分析。

**Topics**
+ [使用 Amazon CloudWatch 指标监控 AWS Glue](monitoring-awsglue-with-cloudwatch-metrics.md)
+ [在 AWS Glue 作业配置文件上设置 Amazon CloudWatch 警报](monitor-profile-glue-job-cloudwatch-alarms.md)
+ [AWS Glue 作业的日志记录](monitor-continuous-logging.md)
+ [使用 AWS Glue 可观测性指标进行监控](monitor-observability.md)

# 使用 Amazon CloudWatch 指标监控 AWS Glue
<a name="monitoring-awsglue-with-cloudwatch-metrics"></a>

您可以使用 AWS Glue 作业分析器分析和监控 AWS Glue 操作。它从 AWS Glue 收集原始数据，并将其处理为 Amazon CloudWatch 中存储的易读且近乎实时的指标。这些统计数据将保留并聚合在 CloudWatch 中，以便您可以访问历史信息，更好地了解您的应用程序的运行状况。

**注意**  
 启用任务指标并且创建 CloudWatch 自定义指标时，可能需要支付额外费用。有关更多信息，请参阅 [Amazon CloudWatch 定价](https://aws.amazon.com/cloudwatch/pricing/)。

## AWS Glue 指标概述
<a name="metrics-overview"></a>

当您与 AWS Glue 交互时，它将指标发送到 CloudWatch。您可以使用 AWS Glue 控制台（首选方法）、CloudWatch 控制台控制面板或 AWS Command Line Interface（AWS CLI）查看这些指标。

**使用 AWS Glue 控制台控制面板查看指标**

您可以查看作业的指标的摘要或详细图表，或作业运行的详细图表。

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

1. 在导航窗格中，选择**作业运行监控**。

1. 在**作业运行**中，选择**操作**以停止当前正在运行的作业、查看作业或倒回作业书签。

1. 选择一个作业，然后选择**查看运行详细信息**以查看有关该作业运行的其他信息。

**使用 CloudWatch 控制台控制面板查看指标**

指标的分组首先依据服务命名空间，然后依据每个命名空间内的各种维度组合。

1. 访问 [https://console.aws.amazon.com/cloudwatch/](https://console.aws.amazon.com/cloudwatch/) 打开 CloudWatch 控制台。

1. 在导航窗格中，选择**指标**。

1. 选择 **Glue** 命名空间。

**使用 AWS CLI 查看指标**
+ 在命令提示符处，使用以下命令。

  ```
  1. aws cloudwatch list-metrics --namespace Glue
  ```

AWS Glue 每隔 30 秒向 CloudWatch 报告一次指标，CloudWatch 指标控制面板配置为每分钟显示一次指标。AWS Glue 指标表示先前报告的值的增量值。在适当时，指标控制面板会聚合（合计）30 秒值以获取整个最后一分钟的值。

### Spark 作业的 AWS Glue 指标行为
<a name="metrics-overview-spark"></a>

 在脚本中初始化 `GlueContext` 时启用 AWS Glue 指标，并且一般仅在 Apache Spark 任务结束时更新这些指标。它们表示迄今为止所有已完成的 Spark 任务的聚合值。

但是，AWS Glue 传递给 CloudWatch 的 Spark 指标通常表示在报告它们时的当前状态的绝对值。AWS Glue 每隔 30 秒向 CloudWatch 报告一次指标，并且指标控制面板通常会显示在最后 1 分钟收到的数据点的平均值。

AWS Glue 指标名称均采用以下类型的前缀之一：
+ `glue.driver.` – 其名称以此前缀开头的指标表示从 Spark 驱动程序上的所有执行程序聚合的 AWS Glue 指标，或对应于 Spark 驱动程序的 Spark 指标。
+ `glue.`*executorId*`.` – *executorId* 是特定 Spark 执行程序的编号。它与日志中列出的执行程序相对应。
+ `glue.ALL.` – 其名称以此前缀开头的指标聚合来自所有 Spark 执行程序的值。

## AWS Glue 指标
<a name="awsglue-metrics"></a>

AWS Glue 会每隔 30 秒配置以下指标并将其发送到 CloudWatch，AWS Glue 指标控制面板每分钟报告一次：


| 指标 | 说明 | 
| --- | --- | 
|  `glue.driver.aggregate.bytesRead` |  所有执行程序中运行的所有已完成的 Spark 任务从所有数据源读取的字节数。 有效维度：`JobName`（AWS Glue 任务的名称）、`JobRunId`（JobRun ID 或 `ALL`）和 `Type`（计数）。 有效统计数据：SUM 此指标是上次报告值的增量值，因此，在 AWS Glue 指标控制面板上，SUM 统计数据用于聚合。 单位：字节 可用于监控： [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/glue/latest/dg/monitoring-awsglue-with-cloudwatch-metrics.html) 此指标可以按 `glue.ALL.s3.filesystem.read_bytes` 指标的方式使用，不同之处在于此指标在 Spark 任务结束时更新并捕获非 S3 数据源。  | 
|  `glue.driver.aggregate.elapsedTime` |  ETL 运行时间（以毫秒为单位，不包括任务的引导启动时间）。 有效维度：`JobName`（AWS Glue 任务的名称）、`JobRunId`（JobRun ID 或 `ALL`）和 `Type`（计数）。 有效统计数据：SUM 此指标是上次报告值的增量值，因此，在 AWS Glue 指标控制面板上，SUM 统计数据用于聚合。 单位：毫秒 可用于确定任务运行的平均时长。 数据的一些使用方式： [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/glue/latest/dg/monitoring-awsglue-with-cloudwatch-metrics.html)  | 
|   `glue.driver.aggregate.numCompletedStages` |  任务中已完成的阶段数量。 有效维度：`JobName`（AWS Glue 任务的名称）、`JobRunId`（JobRun ID 或 `ALL`）和 `Type`（计数）。 有效统计数据：SUM 此指标是上次报告值的增量值，因此，在 AWS Glue 指标控制面板上，SUM 统计数据用于聚合。 单位：个 可用于监控： [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/glue/latest/dg/monitoring-awsglue-with-cloudwatch-metrics.html) 数据的一些使用方式： [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/glue/latest/dg/monitoring-awsglue-with-cloudwatch-metrics.html)  | 
|  `glue.driver.aggregate.numCompletedTasks` |  任务中已完成的任务数量。 有效维度：`JobName`（AWS Glue 任务的名称）、`JobRunId`（JobRun ID 或 `ALL`）和 `Type`（计数）。 有效统计数据：SUM 此指标是上次报告值的增量值，因此，在 AWS Glue 指标控制面板上，SUM 统计数据用于聚合。 单位：个 可用于监控： [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/glue/latest/dg/monitoring-awsglue-with-cloudwatch-metrics.html)  | 
|  `glue.driver.aggregate.numFailedTasks` |  失败的任务数。 有效维度：`JobName`（AWS Glue 任务的名称）、`JobRunId`（JobRun ID 或 `ALL`）和 `Type`（计数）。 有效统计数据：SUM 此指标是上次报告值的增量值，因此，在 AWS Glue 指标控制面板上，SUM 统计数据用于聚合。 单位：个 可用于监控： [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/glue/latest/dg/monitoring-awsglue-with-cloudwatch-metrics.html) 这些数据可用于为增加的故障设置警报，这些故障可能表明数据、集群或脚本出现异常。  | 
|  `glue.driver.aggregate.numKilledTasks` |  已终止的任务数量。 有效维度：`JobName`（AWS Glue 任务的名称）、`JobRunId`（JobRun ID 或 `ALL`）和 `Type`（计数）。 有效统计数据：SUM 此指标是上次报告值的增量值，因此，在 AWS Glue 指标控制面板上，SUM 统计数据用于聚合。 单位：个 可用于监控： [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/glue/latest/dg/monitoring-awsglue-with-cloudwatch-metrics.html) 数据的一些使用方式： [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/glue/latest/dg/monitoring-awsglue-with-cloudwatch-metrics.html)  | 
|  `glue.driver.aggregate.recordsRead` |  所有执行程序中运行的所有已完成的 Spark 任务从所有数据源读取的记录数。 有效维度：`JobName`（AWS Glue 任务的名称）、`JobRunId`（JobRun ID 或 `ALL`）和 `Type`（计数）。 有效统计数据：SUM 此指标是上次报告值的增量值，因此，在 AWS Glue 指标控制面板上，SUM 统计数据用于聚合。 单位：个 可用于监控： [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/glue/latest/dg/monitoring-awsglue-with-cloudwatch-metrics.html) 此指标可以按 `glue.ALL.s3.filesystem.read_bytes` 指标的方式使用，不同之处在于此指标在 Spark 任务结束时更新。  | 
|   `glue.driver.aggregate.shuffleBytesWritten` |  自上次报告以来所有执行程序为在它们之间对数据进行随机排序而写入的字节数（由 AWS Glue 指标控制面板聚合为前一分钟内为此目的写入的字节数）。 有效维度：`JobName`（AWS Glue 任务的名称）、`JobRunId`（JobRun ID 或 `ALL`）和 `Type`（计数）。 有效统计数据：SUM 此指标是上次报告值的增量值，因此，在 AWS Glue 指标控制面板上，SUM 统计数据用于聚合。 单位：字节 可用于监控：任务（大型联接、分组依据、重新分区、合并）中的数据随机排序。 数据的一些使用方式： [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/glue/latest/dg/monitoring-awsglue-with-cloudwatch-metrics.html)  | 
|   `glue.driver.aggregate.shuffleLocalBytesRead` |  自上次报告以来所有执行程序为在它们之间对数据进行随机排序而读取的字节数（由 AWS Glue 指标控制面板聚合为前一分钟内为此目的读取的字节数）。 有效维度：`JobName`（AWS Glue 任务的名称）、`JobRunId`（JobRun ID 或 `ALL`）和 `Type`（计数）。 有效统计数据：SUM 此指标是上次报告值的增量值，因此，在 AWS Glue 指标控制面板上，SUM 统计数据用于聚合。 单位：字节 可用于监控：任务（大型联接、分组依据、重新分区、合并）中的数据随机排序。 数据的一些使用方式： [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/glue/latest/dg/monitoring-awsglue-with-cloudwatch-metrics.html)  | 
|  `glue.driver.BlockManager.disk.diskSpaceUsed_MB` |  所有执行程序中所用磁盘空间的兆字节数。 有效维度：`JobName`（AWS Glue 任务的名称）、`JobRunId`（JobRun ID 或 `ALL`）和 `Type`（量规）。 有效统计数据：平均值。这是 Spark 指标，报告为绝对值。 单位：兆字节 可用于监控： [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/glue/latest/dg/monitoring-awsglue-with-cloudwatch-metrics.html) 数据的一些使用方式： [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/glue/latest/dg/monitoring-awsglue-with-cloudwatch-metrics.html)  | 
|   `glue.driver.ExecutorAllocationManager.executors.numberAllExecutors` |  主动运行的执行程序的数量。 有效维度：`JobName`（AWS Glue 任务的名称）、`JobRunId`（JobRun ID 或 `ALL`）和 `Type`（量规）。 有效统计数据：平均值。这是 Spark 指标，报告为绝对值。 单位：个 可用于监控： [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/glue/latest/dg/monitoring-awsglue-with-cloudwatch-metrics.html) 数据的一些使用方式： [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/glue/latest/dg/monitoring-awsglue-with-cloudwatch-metrics.html)  | 
|   `glue.driver.ExecutorAllocationManager.executors.numberMaxNeededExecutors` |  为满足当前负载所需的最大（主动运行和待处理）任务执行程序的数量。 有效维度：`JobName`（AWS Glue 任务的名称）、`JobRunId`（JobRun ID 或 `ALL`）和 `Type`（量规）。 有效统计数据：最大值 这是 Spark 指标，报告为绝对值。 单位：个 可用于监控： [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/glue/latest/dg/monitoring-awsglue-with-cloudwatch-metrics.html) 数据的一些使用方式： [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/glue/latest/dg/monitoring-awsglue-with-cloudwatch-metrics.html)  | 
|   `glue.driver.jvm.heap.usage`  `glue.`*executorId*`.jvm.heap.usage`  `glue.ALL.jvm.heap.usage`  |  驱动程序的 JVM 堆用于此驱动程序的内存量（比例：0-1），executorId 标识的执行程序，或所有执行程序。 有效维度：`JobName`（AWS Glue 任务的名称）、`JobRunId`（JobRun ID 或 `ALL`）和 `Type`（量规）。 有效统计数据：平均值。这是 Spark 指标，报告为绝对值。 单位：百分比 可用于监控： [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/glue/latest/dg/monitoring-awsglue-with-cloudwatch-metrics.html) 数据的一些使用方式： [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/glue/latest/dg/monitoring-awsglue-with-cloudwatch-metrics.html)  | 
|  `glue.driver.jvm.heap.used`  `glue.`*executorId*`.jvm.heap.used`  `glue.ALL.jvm.heap.used`  |  驱动程序的 JVM 堆所用的内存字节数，*executorId* 表示的执行程序或所有执行程序。 有效维度：`JobName`（AWS Glue 任务的名称）、`JobRunId`（JobRun ID 或 `ALL`）和 `Type`（量规）。 有效统计数据：平均值。这是 Spark 指标，报告为绝对值。 单位：字节 可用于监控： [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/glue/latest/dg/monitoring-awsglue-with-cloudwatch-metrics.html) 数据的一些使用方式： [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/glue/latest/dg/monitoring-awsglue-with-cloudwatch-metrics.html)  | 
|   `glue.driver.s3.filesystem.read_bytes`  `glue.`*executorId*`.s3.filesystem.read_bytes`  `glue.ALL.s3.filesystem.read_bytes`  |  自上次报告以来，驱动程序、*executorId* 标识的执行程序、所有执行程序从 Amazon S3 读取的字节数（由 AWS Glue 指标控制面板聚合为上一分钟内读取的字节数）。 有效维度：`JobName`、`JobRunId` 和 `Type`（量规）。 有效统计数据：SUM 此指标是上次报告值的增量值，因此，在 AWS Glue 指标控制面板上，SUM 统计数据用于聚合。AWS Glue 指标控制面板上曲线下面的区域可用于直观比较两个不同任务运行读取的字节。 单位：字节。 可用于监控： [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/glue/latest/dg/monitoring-awsglue-with-cloudwatch-metrics.html) 生成的数据可用于： [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/glue/latest/dg/monitoring-awsglue-with-cloudwatch-metrics.html)  | 
|   `glue.driver.s3.filesystem.write_bytes`  `glue.`*executorId*`.s3.filesystem.write_bytes`  `glue.ALL.s3.filesystem.write_bytes`  |  自上次报告以来，驱动程序、*executorId* 标识的执行程序、所有执行程序从 Amazon S3 写入的字节数（由 AWS Glue 指标控制面板聚合为上一分钟内写入的字节数）。 有效维度：`JobName`、`JobRunId` 和 `Type`（量规）。 有效统计数据：SUM 此指标是上次报告值的增量值，因此，在 AWS Glue 指标控制面板上，SUM 统计数据用于聚合。AWS Glue 指标控制面板上曲线下面的区域可用于直观比较两个不同任务运行写入的字节。 单位：字节 可用于监控： [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/glue/latest/dg/monitoring-awsglue-with-cloudwatch-metrics.html) 数据的一些使用方式： [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/glue/latest/dg/monitoring-awsglue-with-cloudwatch-metrics.html)  | 
|  `glue.driver.streaming.numRecords` |  微批处理中接收的记录数。此指标仅适用于 AWS Glue 流式传输任务（采用 AWS Glue 2.0 版及更高版本）。 有效维度：`JobName`（AWS Glue 任务的名称）、`JobRunId`（JobRun ID 或 `ALL`）和 `Type`（计数）。 有效统计数据：总计、最大值、最小值、平均值、百分比 单位：个 可用于监控： [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/glue/latest/dg/monitoring-awsglue-with-cloudwatch-metrics.html)  | 
|  `glue.driver.streaming.batchProcessingTimeInMs` |  处理批处理所需的时间（以毫秒为单位）。此指标仅适用于 AWS Glue 流式传输任务（采用 AWS Glue 2.0 版及更高版本）。 有效维度：`JobName`（AWS Glue 任务的名称）、`JobRunId`（JobRun ID 或 `ALL`）和 `Type`（计数）。 有效统计数据：总计、最大值、最小值、平均值、百分比 单位：个 可用于监控： [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/glue/latest/dg/monitoring-awsglue-with-cloudwatch-metrics.html)  | 
|   `glue.driver.system.cpuSystemLoad`  `glue.`*executorId*`.system.cpuSystemLoad`  `glue.ALL.system.cpuSystemLoad`  |  驱动程序使用的 CPU 系统负载量（比例：0-1），*executorId* 标识的执行程序，或所有执行程序。 有效维度：`JobName`（AWS Glue 任务的名称）、`JobRunId`（JobRun ID 或 `ALL`）和 `Type`（量规）。 有效统计数据：平均值。此指标报告为绝对值。 单位：百分比 可用于监控： [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/glue/latest/dg/monitoring-awsglue-with-cloudwatch-metrics.html) 数据的一些使用方式： [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/glue/latest/dg/monitoring-awsglue-with-cloudwatch-metrics.html)  | 

## AWS Glue 指标的维度
<a name="awsglue-metricdimensions"></a>

AWS Glue 指标使用 AWS Glue 命名空间并提供以下维度的指标。


| 维度 | 说明 | 
| --- | --- | 
|  `JobName`  |  此维度筛选特定 AWS Glue 任务的所有任务运行的指标。  | 
|  `JobRunId`  |  此维度按 JobRun ID 或 `ALL` 筛选特定 AWS Glue 任务的所有任务运行的指标。  | 
|  `Type`  |  此维度按 `count`（总数）或 `gauge`（在某个时间点的值）筛选指标。  | 

有关更多信息，请参阅《[Amazon CloudWatch 用户指南](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/)》。

# 在 AWS Glue 作业配置文件上设置 Amazon CloudWatch 警报
<a name="monitor-profile-glue-job-cloudwatch-alarms"></a>

AWS Glue 指标还可用于 Amazon CloudWatch。您可以对已计划作业的任何 AWS Glue 指标设置警报。

设置警报的一些常见方案如下所示：
+ 作业内存不足 (OOM)：在内存使用量超过 AWS Glue 作业的驱动程序或执行程序的正常平均值时设置警报。
+ 落后的执行程序：在 AWS Glue 作业中执行程序的数量在较长一段时间内低于特定阈值时设置警报。
+ 数据积压或再处理：使用 CloudWatch 数学表达式比较工作流中单个任务的指标。然后，您可以对生成的表达式值（如作业写入的字节比率和以下作业读取的字节比率）触发警报。

有关设置警报的详细说明，请参阅[《Amazon CloudWatch Events 用户指南》](https://docs.aws.amazon.com/AmazonCloudWatch/latest/events/)**中的[创建或编辑 CloudWatch 警报](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/ConsoleAlarms.html)。

有关使用 CloudWatch 监控和调试场景的信息，请参阅[作业监控和调试](monitor-profile-glue-job-cloudwatch-metrics.md)。

# AWS Glue 作业的日志记录
<a name="monitor-continuous-logging"></a>

 在 AWS Glue 5.0 中，所有作业都具有实时日志记录功能。此外，您可以通过指定自定义配置选项来自定义日志记录行为，包括设置 Amazon CloudWatch 日志组名称、Amazon CloudWatch 日志流前缀（将添加到 AWS Glue 作业运行 ID 和驱动程序/执行程序 ID 之前）以及日志消息的日志转换模式等。借助这些配置，您可以将日志聚合到具有不同过期策略的自定义 Amazon CloudWatch 日志组中。此外，您还可以使用自定义日志流前缀和转换模式来更有效地分析日志。借助这种自定义级别，您可以根据自己的具体需求优化日志管理和分析。

## AWS Glue 5.0 中的日志记录行为
<a name="monitor-logging-behavior-glue-50"></a>

 默认情况下，系统日志、Spark 进程守护程序日志、和用户 AWS Glue Logger 日志都会写入 Amazon CloudWatch 中的 `/aws-glue/jobs/error` 日志组，而用户 stdout（标准输出）和 stderr（标准错误）日志则会默认写入 `/aws-glue/jobs/output` 日志组。

## 自定义日志记录
<a name="monitor-logging-custom"></a>

 您可以使用以下作业参数来自定义默认日志组和日志流前缀：
+  `--custom-logGroup-prefix`：让您能够为 `/aws-glue/jobs/error` 和 `/aws-glue/jobs/output` 日志组指定自定义前缀。如果您提供了自定义前缀，则日志组名称将为以下格式：
  +  `/aws-glue/jobs/error` 将为 `<customer prefix>/error` 
  +  `/aws-glue/jobs/output ` 将为 `<customer prefix>/output` 
+  `--custom-logStream-prefix`：让您能够为日志组内的日志流名称指定自定义前缀。如果您提供了自定义前缀，则日志流名称将为以下格式：
  +  `jobrunid-driver` 将为 `<customer log stream>-driver` 
  +  `jobrunid-executorNum` 将为 `<customer log stream>-executorNum` 

 自定义前缀的验证规则和限制：
+  完整日志流名称长度必须介于 1 到 512 个字符之间。
+  自定义前缀本身的长度不应超过 400 个字符。
+  自定义前缀必须匹配正则表达式模式“[^:\$1]\$1”（允许的特殊字符为“\$1”、“-”和“/”）。

## 使用自定义脚本日志记录程序记录特定于应用程序的消息
<a name="monitor-logging-script"></a>

您可以使用 AWS Glue 日志记录程序记录在脚本中记录任何特定于应用程序的消息，这些消息实时发送到驱动程序日志流。

以下示例显示了一个 Python 脚本。

```
from awsglue.context import GlueContext
from pyspark.context import SparkContext

sc = SparkContext()
glueContext = GlueContext(sc)
logger = glueContext.get_logger()
logger.info("info message")
logger.warn("warn message")
logger.error("error message")
```

以下示例显示了一个 Scala 脚本。

```
import com.amazonaws.services.glue.log.GlueLogger

object GlueApp {
  def main(sysArgs: Array[String]) {
    val logger = new GlueLogger
    logger.info("info message")
    logger.warn("warn message")
    logger.error("error message")
  }
}
```

## 启用进度栏以显示作业进度
<a name="monitor-logging-progress"></a>

AWS Glue 在 `JOB_RUN_ID-progress-bar` 日志流下提供了实时进度栏，用于查看 AWS Glue 作业运行状态。目前，它仅支持初始化 `glueContext` 的作业。如果您运行纯 Spark 作业而没有初始化 `glueContext`，则不显示 AWS Glue 进度栏。

进度栏每 5 秒显示下列进度更新。

```
Stage Number (Stage Name): > (numCompletedTasks + numActiveTasks) / totalNumOfTasksInThisStage]
```

## Amazon CloudWatch 日志记录的安全配置
<a name="monitor-security-config-logging"></a>

 为 Amazon CloudWatch 日志启用安全配置后，AWS Glue 会使用包含安全配置名称的特定命名模式创建日志组。

### 包含安全配置的日志组命名规范
<a name="monitor-log-group-naming"></a>

 默认日志组和自定义日志组将如下所示：
+  **默认错误日志组：**`/aws-glue/jobs/Security-Configuration-Name-role/glue-job-role/error`
+  **默认输出日志组：**`/aws-glue/jobs/Security-Configuration-Name-role/glue-job-role/output`
+  **自定义错误日志组（AWS Glue 5.0）：**`custom-log-group-prefix/Security-Configuration-Name-role/glue-job-role/error`
+  **自定义输出日志组（AWS Glue 5.0）：**`custom-log-group-prefix/Security-Configuration-Name-role/glue-job-role/output`

### 必需的 IAM 权限
<a name="monitor-logging-iam-permissions"></a>

 您需要将 `logs:AssociateKmsKey` 权限添加到您的 IAM 角色权限中（如果您使用 Amazon CloudWatch Logs 启用了安全配置）。如果不包括该权限，连续日志记录将禁用。

 此外，要为 Amazon CloudWatch Logs 配置加密，请遵循《Amazon Amazon CloudWatch Logs 用户指南》中 [Encrypt Log Data in Amazon CloudWatch Logs Using AWS Key Management Service](https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/encrypt-log-data-kms.html) 部分的说明。

### 附加信息
<a name="additional-info"></a>

 有关创建安全配置的更多信息，请参阅[在 AWS Glue 控制台上管理安全配置](https://docs.aws.amazon.com/glue/latest/dg/console-security-configurations.html)。

**Topics**
+ [AWS Glue 5.0 中的日志记录行为](#monitor-logging-behavior-glue-50)
+ [自定义日志记录](#monitor-logging-custom)
+ [使用自定义脚本日志记录程序记录特定于应用程序的消息](#monitor-logging-script)
+ [启用进度栏以显示作业进度](#monitor-logging-progress)
+ [Amazon CloudWatch 日志记录的安全配置](#monitor-security-config-logging)
+ [为 AWS Glue 4.0 和更早期版本作业启用连续日志记录](monitor-continuous-logging-enable.md)
+ [查看 AWS Glue 作业的日志](monitor-continuous-logging-view.md)

# 为 AWS Glue 4.0 和更早期版本作业启用连续日志记录
<a name="monitor-continuous-logging-enable"></a>

**注意**  
 AWS Glue 4.0 及更早期版本提供了连续日志记录功能。但在 AWS Glue 5.0 推出后，所有作业都已具有实时日志记录功能。有关 AWS Glue 5.0 中日志记录功能和配置选项的更多详细信息，请参阅 [AWS Glue 作业的日志记录](https://docs.aws.amazon.com/glue/latest/dg/monitor-continuous-logging.html)。

您可使用 AWS Glue 控制台或通过 AWS Command Line Interface (AWS CLI) 启用连续日志记录。

您可以在创建新作业或编辑现有作业时启用连续日志记录，也可通过 AWS CLI 启用此功能。

您还可以指定自定义配置选项，例如 Amazon CloudWatch 日志组名称、AWS Glue 任务运行 ID 驱动程序/执行程序 ID 之前的 CloudWatch 日志流前缀，以及日志消息的日志转换模式。这些配置可帮助您在具有不同到期策略的自定义 CloudWatch 日志组中设置聚合日志，并使用自定义日志流前缀和转换模式对它们进行进一步分析。

**Topics**
+ [使用 AWS 管理控制台](#monitor-continuous-logging-enable-console)
+ [使用自定义脚本日志记录程序记录特定于应用程序的消息](#monitor-continuous-logging-script)
+ [启用进度栏以显示作业进度](#monitor-continuous-logging-progress)
+ [采用连续日志记录的安全配置](#monitor-logging-encrypt-log-data)

## 使用 AWS 管理控制台
<a name="monitor-continuous-logging-enable-console"></a>

在创建或编辑 AWS Glue 作业时，按照以下步骤使用控制台来启用连续日志记录。

**创建带有连续日志记录的新 AWS Glue 作业**

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

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

1. 选择 **Visual ETL**。

1. 在**作业详细信息**选项卡中，展开**高级属性**部分。

1. 在**持续日志记录**下，选择**启用 CloudWatch 中的日志**。

**为现有 AWS Glue 作业启用连续日志记录**

1. 通过 [https://console.aws.amazon.com/glue/](https://console.aws.amazon.com/glue/) 打开 AWS Glue 控制台。

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

1. 从**作业**列表选择现有作业。

1. 选择**操作**和**编辑作业**。

1. 在**作业详细信息**选项卡中，展开**高级属性**部分。

1. 在**持续日志记录**下，选择**启用 CloudWatch 中的日志**。

### 使用 AWS CLI
<a name="monitor-continuous-logging-cli"></a>

要启用连续日志记录，您需要将作业参数传入 AWS Glue 作业。通过类似于其他 AWS Glue 作业参数的方法，传递以下特殊作业参数。有关更多信息，请参阅 [在 AWS Glue 作业中使用作业参数](aws-glue-programming-etl-glue-arguments.md)。

```
'--enable-continuous-cloudwatch-log': 'true'
```

您可以指定自定义 Amazon CloudWatch 日志组名称。如果未指定，则默认日志组名称为 `/aws-glue/jobs/logs-v2`。

```
'--continuous-log-logGroup': 'custom_log_group_name'
```

您可以指定自定义 Amazon CloudWatch 日志流前缀。如果未指定，则默认日志流前缀为作业运行 ID。

```
'--continuous-log-logStreamPrefix': 'custom_log_stream_prefix'
```

您可以指定自定义连续日志记录转换模式。如果未指定，则默认转换模式为 `%d{yy/MM/dd HH:mm:ss} %p %c{1}: %m%n`。请注意，转换模式仅适用于驱动程序日志和执行程序日志。它不会影响 AWS Glue 进度条。

```
'--continuous-log-conversionPattern': 'custom_log_conversion_pattern'
```

## 使用自定义脚本日志记录程序记录特定于应用程序的消息
<a name="monitor-continuous-logging-script"></a>

您可以使用 AWS Glue 日志记录程序记录在脚本中记录任何特定于应用程序的消息，这些消息实时发送到驱动程序日志流。

以下示例显示了一个 Python 脚本。

```
from awsglue.context import GlueContext
from pyspark.context import SparkContext

sc = SparkContext()
glueContext = GlueContext(sc)
logger = glueContext.get_logger()
logger.info("info message")
logger.warn("warn message")
logger.error("error message")
```

以下示例显示了一个 Scala 脚本。

```
import com.amazonaws.services.glue.log.GlueLogger

object GlueApp {
  def main(sysArgs: Array[String]) {
    val logger = new GlueLogger
    logger.info("info message")
    logger.warn("warn message")
    logger.error("error message")
  }
}
```

## 启用进度栏以显示作业进度
<a name="monitor-continuous-logging-progress"></a>

AWS Glue 在 `JOB_RUN_ID-progress-bar` 日志流下提供了实时进度栏，用于查看 AWS Glue 作业运行状态。目前，它仅支持初始化 `glueContext` 的作业。如果您运行纯 Spark 作业而没有初始化 `glueContext`，则不显示 AWS Glue 进度栏。

进度栏每 5 秒显示下列进度更新。

```
Stage Number (Stage Name): > (numCompletedTasks + numActiveTasks) / totalNumOfTasksInThisStage]
```

## 采用连续日志记录的安全配置
<a name="monitor-logging-encrypt-log-data"></a>

如果为 CloudWatch 日志启用了安全配置，AWS Glue 将为连续日志创建一个名称如下的日志组：

```
<Log-Group-Name>-<Security-Configuration-Name>
```

默认日志组和自定义日志组将如下所示：
+ 默认连续日志组将为 `/aws-glue/jobs/error-<Security-Configuration-Name>`
+ 自定义连续日志组将为 `<custom-log-group-name>-<Security-Configuration-Name>`

您需要将 `logs:AssociateKmsKey` 添加到您的 IAM 角色权限（如果您使用 CloudWatch Logs 启用了安全配置）。如果不包括该权限，连续日志记录将禁用。此外，要为 CloudWatch Logs 配置加密，请遵循《Amazon CloudWatch Logs 用户指南》**中的[使用 AWS Key Management Service 加密 CloudWatch Logs 中日志数据](https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/encrypt-log-data-kms.html)处的说明。

有关创建安全配置的更多信息，请参阅 [在 AWS Glue 控制台上管理安全配置](console-security-configurations.md)。

**注意**  
 启用日志记录并创建额外的 CloudWatch 日志事件时，可能会产生额外的费用。有关更多信息，请参阅 [Amazon CloudWatch 定价](https://aws.amazon.com/cloudwatch/pricing/)。

# 查看 AWS Glue 作业的日志
<a name="monitor-continuous-logging-view"></a>

您可以使用 AWS Glue 控制台或 Amazon CloudWatch 控制台查看实时日志。

**使用 AWS Glue 控制台控制面板查看实时日志**

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

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

1. 添加或启动现有作业。选择**操作**、**运行作业**。

   在您开始运行某个作业时，系统会将您导航到包含该运行作业相关信息的页面：
   + **日志**显示之前的已聚合应用程序日志。
   + 在初始化了 `glueContext` 的作业运行时，**日志**选项卡会显示一个实时进度条。
   + **日志**选项卡还包含**驱动程序日志**（用于捕获实时 Apache Spark 驱动程序日志），以及应用程序日志（来自在作业运行时使用 AWS Glue 应用程序日志记录程序记录的脚本）。

1. 对于较早的任务，您还可以选择 **Logs (日志)**，在 **Job History (任务历史记录)** 视图下面查看实时日志。此操作会将您转到显示所有 Spark 进度栏、执行程序及该任务运行的进度栏日志流的 CloudWatch 控制台。

**使用 CloudWatch 控制台控制面板查看实时日志**

1. 通过 [https://console.aws.amazon.com/cloudwatch/](https://console.aws.amazon.com/cloudwatch/) 打开 CloudWatch 控制台。

1. 在导航窗格选择**日志**。

1. 选择 **/aws-glue/jobs/error/** 日志组。

1. 在**筛选条件**框中，粘贴作业运行 ID。

   您可以查看驱动程序日志、执行程序日志和进度栏（如果使用 **标准筛选条件**）。

# 使用 AWS Glue 可观测性指标进行监控
<a name="monitor-observability"></a>

**注意**  
AWS Glue 可观测性指标在 AWS Glue 4.0 及更高版本中可用。

 使用 AWS Glue 可观测性指标可深入了解 AWS Glue 内部发生的情况，以便 Apache Spark 作业可以改进对问题的分类和分析。可观测性指标通过 Amazon CloudWatch 控制面板进行可视化显示，有助于分析错误的根本原因以及诊断性能瓶颈。您可以缩短大规模问题调试所需的时间，从而专注于更快、更有效地解决问题。

 AWS Glue 可观测性提供了以下四组 Amazon CloudWatch 指标：
+  **可靠性（即错误类别）**– 可轻松确定给定时间范围内可能需要解决的最常见故障原因。
+  **性能（即偏斜）**– 确定性能瓶颈并应用优化技术。例如，性能因作业偏斜而下降时，可能需要启用 Spark 自适应查询执行并微调优化偏斜联接阈值。
+  **吞吐量（即每源/接收器吞吐量）**– 监控数据读取和写入的趋势。您还可以针对异常配置 Amazon CloudWatch 警报。
+  **资源利用率（即 Worker 线程、内存和磁盘利用率）**– 高效地查找容量利用率低的作业。您可能需要为这些作业启用 AWS Glue 自动扩缩。

## AWS Glue 可观测性指标入门
<a name="monitor-observability-getting-started"></a>

**注意**  
 默认情况下，新指标在 AWS Glue Studio 控制台中已启用。

**在 AWS Glue Studio 中配置可观测性指标：**

1. 登录 AWS Glue 控制台并从控制台菜单中选择 **ETL 作业**。

1. 单击**您的作业**部分中的作业名称，从而选择作业。

1. 选择 **Job details**（任务详细信息）选项卡。

1. 滚动到底部并选择**高级属性**，然后选择**作业可观测性指标**。  
![\[屏幕截图显示了“作业详细信息”页面的“高级属性”选项卡。“作业可观测性指标”选项已突出显示。\]](http://docs.aws.amazon.com/zh_cn/glue/latest/dg/images/job-details-observability-metrics.png)

**通过 AWS CLI 启用 AWS Glue 可观测性指标：**
+  将输入 JSON 文件中的以下键值添加到 `--default-arguments` 映射中：

  ```
  --enable-observability-metrics, true
  ```

## 使用 AWS Glue 可观测性
<a name="monitor-observability-cloudwatch"></a>

 由于 AWS Glue 可观测性指标是通过 Amazon CloudWatch 提供的，因此您可以通过 Amazon CloudWatch 控制台、AWS CLI、SDK 或 API 来查询可观测性指标数据点。有关何时使用 AWS Glue 可观测性指标的示例用例，请参阅 [Using Glue Observability for monitoring resource utilization to reduce cost](https://aws.amazon.com/blogs/big-data/enhance-monitoring-and-debugging-for-aws-glue-jobs-using-new-job-observability-metrics/)。

### 在 Amazon CloudWatch 控制台中使用 AWS Glue 可观测性
<a name="monitor-observability-cloudwatch-console"></a>

**在 Amazon CloudWatch 控制台中查询和可视化显示指标：**

1.  打开 Amazon CloudWatch 控制台，然后选择 **所有指标**。

1.  在“自定义命名空间”下，选择 **AWS Glue**。

1.  选择**作业可观测性指标、每源可观测性指标或每接收器可观测性指标**。

1. 搜索特定的指标名称、作业名称、作业运行 ID，然后将其选中。

1. 在**图形化指标**选项卡下，配置您的首选统计数据、周期和其他选项。  
![\[屏幕截图显示了 Amazon CloudWatch 控制台和指标图。\]](http://docs.aws.amazon.com/zh_cn/glue/latest/dg/images/cloudwatch-console-metrics.png)

**使用 AWS CLI 查询可观测性指标：**

1.  创建指标定义 JSON 文件并将 `your-Glue-job-name` 和 `your-Glue-job-run-id` 替换为您的值。

   ```
   $ cat multiplequeries.json
   [
       {
           "Id": "avgWorkerUtil_0",
           "MetricStat": {
               "Metric": {
                   "Namespace": "Glue",
                   "MetricName": "glue.driver.workerUtilization",
                   "Dimensions": [
                       {
                           "Name": "JobName",
                           "Value": "<your-Glue-job-name-A>"
                       },
                       {
                           "Name": "JobRunId",
                           "Value": "<your-Glue-job-run-id-A>"
                       },
                       {
                           "Name": "Type",
                           "Value": "gauge"
                       },
                       {
                           "Name": "ObservabilityGroup",
                           "Value": "resource_utilization"
                       }
                   ]
               },
               "Period": 1800,
               "Stat": "Minimum",
               "Unit": "None"
           }
       },
       {
           "Id": "avgWorkerUtil_1",
           "MetricStat": {
               "Metric": {
                   "Namespace": "Glue",
                   "MetricName": "glue.driver.workerUtilization",
                   "Dimensions": [
                       {
                           "Name": "JobName",
                           "Value": "<your-Glue-job-name-B>"
                       },
                       {
                           "Name": "JobRunId",
                           "Value": "<your-Glue-job-run-id-B>"
                       },
                       {
                           "Name": "Type",
                           "Value": "gauge"
                       },
                       {
                           "Name": "ObservabilityGroup",
                           "Value": "resource_utilization"
                       }
                   ]
               },
               "Period": 1800,
               "Stat": "Minimum",
               "Unit": "None"
           }
       }
   ]
   ```

1.  运行 `get-metric-data` 命令：

   ```
   $ aws cloudwatch get-metric-data --metric-data-queries file: //multiplequeries.json \
        --start-time '2023-10-28T18: 20' \
        --end-time '2023-10-28T19: 10'  \
        --region us-east-1
   {
       "MetricDataResults": [
           {
               "Id": "avgWorkerUtil_0",
               "Label": "<your-label-for-A>",
               "Timestamps": [
                   "2023-10-28T18:20:00+00:00"
               ],
               "Values": [
                   0.06718750000000001
               ],
               "StatusCode": "Complete"
           },
           {
               "Id": "avgWorkerUtil_1",
               "Label": "<your-label-for-B>",
               "Timestamps": [
                   "2023-10-28T18:50:00+00:00"
               ],
               "Values": [
                   0.5959183673469387
               ],
               "StatusCode": "Complete"
           }
       ],
       "Messages": []
   }
   ```

## 可观测性指标
<a name="monitor-observability-metrics-definitions"></a>

 AWS Glue 可观测性每隔 30 秒分析以下指标并将其发送到 Amazon CloudWatch，其中一些指标可以在 AWS Glue Studio 作业运行监测页面中看到。


| 指标 | 说明 | 类别 | 
| --- | --- | --- | 
| glue.driver.skewness.stage |  指标类别：job\$1performance Spark 分阶段执行偏度：该指标反映特定阶段内最长任务持续时间与该阶段任务持续时间中位数相比的差异程度。此指标捕获执行偏度，这可能是由输入数据偏度或转换（例如，偏斜联接）引起的。该指标值的范围是 [0, 无穷大]，其中 0 表示该阶段中所有任务中最长任务执行时间与中值任务执行时间的比率，小于某个阶段偏度系数。默认的阶段偏度系数为“5”，可以通过 spark conf 进行覆盖：spark.metrics.conf.driver.source.glue.jobPerformance.skewnessFactor 阶段偏度值为 1 表示该比率是阶段偏度系数的两倍。 阶段偏度值每 30 秒更新一次，以反映当前偏度。阶段结束时的值反映了最终阶段偏度。 此阶段级指标用于计算作业级指标 `glue.driver.skewness.job`。 有效维度：JobName（AWS Glue 作业名称）、JobRunId（JobRun ID 或 ALL）、Type（量规）和 ObservabilityGroup (job\$1performance) 有效统计信息：平均值、最大值、最小值、百分比 单位：个  | job\$1performance | 
| glue.driver.skewness.job |  指标类别：job\$1performance  作业偏度是所有阶段加权偏度的最大值。阶段偏度 (glue.driver.skewness.stage) 采用阶段持续时间加权计算。这是为了避免极端的情况，即一个非常偏斜的阶段相对于其他阶段实际上运行的时间很短（因此其偏度对整体作业性能并不重要，也没必要费力解决其偏度）。 该指标在每个阶段完成后更新，因此最后一个值反映了实际的整体作业偏度。 有效维度：JobName（AWS Glue 作业名称）、JobRunId（JobRun ID 或 ALL）、Type（量规）和 ObservabilityGroup（job\$1performance） 有效统计信息：平均值、最大值、最小值、百分比 单位：个  | job\$1performance | 
| glue.succeed.ALL |  指标类别：错误 成功运行的作业总数，以全面了解失败类别 有效维度：JobName（AWS Glue 作业名称）、JobRunId（JobRun ID 或 ALL）、Type（计数）和 ObservabilityGroup（错误） 有效统计信息：SUM 单位：个  | 错误 | 
| glue.error.ALL |  指标类别：错误  作业运行错误总数，以全面了解失败类别 有效维度：JobName（AWS Glue 作业名称）、JobRunId（JobRun ID 或 ALL）、Type（计数）和 ObservabilityGroup（错误） 有效统计信息：SUM 单位：个  | 错误 | 
| glue.error.[错误类别] |  指标类别：错误  这实际上是一组指标，只有在作业运行失败时才会更新。错误分类有助于分类和调试。作业运行失败时，会对导致失败的错误进行分类，并将相应的错误类别指标设置为 1。这有助于执行一段时间内的故障分析，以及对所有作业进行错误分析，以确定最常见的失败类别并开始解决这些问题。AWS Glue 有 28 个错误类别，包括 OUT\$1OF\$1MEMORY（驱动程序和执行程序）、PERMISSION、SYNTAX 和 THROTTLING 错误类别。错误类别还包括 COMPILATION、LAUNCH 和 TIMEOUT 错误类别。 有效维度：JobName（AWS Glue 作业名称）、JobRunId（JobRun ID 或 ALL）、Type（计数）和 ObservabilityGroup（错误） 有效统计信息：SUM 单位：个  | 错误 | 
| glue.driver.workerUtilization |  指标类别：resource\$1utilization  实际使用的已分配工作人员的百分比。如果效果不佳，自动扩缩功能可以提供帮助。 有效维度：JobName（AWS Glue 作业名称）、JobRunId（JobRun ID 或 ALL）、Type（量规）和 ObservabilityGroup（resource\$1utilization） 有效统计信息：平均值、最大值、最小值、百分比 单位：百分比  | resource\$1utilization | 
| glue.driver.memory.heap.[available \$1 used] |  指标类别：resource\$1utilization  作业运行期间，驱动程序的可用/已用堆内存。这有助于了解内存使用趋势，尤其是随时间推移而来的内存使用趋势，从而能帮助避免潜在的故障，此外还可以调试与内存相关的故障。 有效维度：JobName（AWS Glue 作业名称）、JobRunId（JobRun ID 或 ALL）、Type（量规）和 ObservabilityGroup（resource\$1utilization） 有效统计信息：平均值 单位：字节  | resource\$1utilization | 
| glue.driver.memory.heap.used.percentage |  指标类别：resource\$1utilization  作业运行期间，驱动程序的已用堆内存（%）。这有助于了解内存使用趋势，尤其是随时间推移而来的内存使用趋势，从而能帮助避免潜在的故障，此外还可以调试与内存相关的故障。 有效维度：JobName（AWS Glue 作业名称）、JobRunId（JobRun ID 或 ALL）、Type（量规）和 ObservabilityGroup（resource\$1utilization） 有效统计信息：平均值 单位：百分比  | resource\$1utilization | 
| glue.driver.memory.non-heap.[available \$1 used] |  指标类别：resource\$1utilization  作业运行期间，驱动程序的可用/已用非堆内存。这有助于了解内存使用趋势，尤其是随时间推移而来的内存使用趋势，这有助于避免潜在的故障，此外还可以调试与内存相关的故障。 有效维度：JobName（AWS Glue 作业名称）、JobRunId（JobRun ID 或 ALL）、Type（量规）和 ObservabilityGroup（resource\$1utilization） 有效统计信息：平均值 单位：字节  | resource\$1utilization | 
| glue.driver.memory.non-heap.used.percentage |  指标类别：resource\$1utilization  作业运行期间，驱动程序的已用非堆内存（%）。这有助于了解内存使用趋势，尤其是随时间推移而来的内存使用趋势，从而能帮助避免潜在的故障，此外还可以调试与内存相关的故障。 有效维度：JobName（AWS Glue 作业名称）、JobRunId（JobRun ID 或 ALL）、Type（量规）和 ObservabilityGroup（resource\$1utilization） 有效统计信息：平均值 单位：百分比  | resource\$1utilization | 
| glue.driver.memory.total.[available \$1 used] |  指标类别：resource\$1utilization  作业运行期间，驱动程序的可用/已用总内存。这有助于了解内存使用趋势，尤其是随时间推移而来的内存使用趋势，从而能帮助避免潜在的故障，此外还可以调试与内存相关的故障。 有效维度：JobName（AWS Glue 作业名称）、JobRunId（JobRun ID 或 ALL）、Type（量规）和 ObservabilityGroup（resource\$1utilization） 有效统计信息：平均值 单位：字节  | resource\$1utilization | 
| glue.driver.memory.total.used.percentage |  指标类别：resource\$1utilization  作业运行期间，驱动程序的已用总内存（%）。这有助于了解内存使用趋势，尤其是随时间推移而来的内存使用趋势，从而能帮助避免潜在的故障，此外还可以调试与内存相关的故障。 有效维度：JobName（AWS Glue 作业名称）、JobRunId（JobRun ID 或 ALL）、Type（量规）和 ObservabilityGroup（resource\$1utilization） 有效统计信息：平均值 单位：百分比  | resource\$1utilization | 
| glue.ALL.memory.heap.[available \$1 used] |  指标类别：resource\$1utilization  执行程序的可用/已用堆内存。ALL 表示所有执行程序。 有效维度：JobName（AWS Glue 作业名称）、JobRunId（JobRun ID 或 ALL）、Type（量规）和 ObservabilityGroup（resource\$1utilization） 有效统计信息：平均值 单位：字节  | resource\$1utilization | 
| glue.ALL.memory.heap.used.percentage |  指标类别：resource\$1utilization  执行程序的已用堆内存（%）。ALL 表示所有执行程序。 有效维度：JobName（AWS Glue 作业名称）、JobRunId（JobRun ID 或 ALL）、Type（量规）和 ObservabilityGroup（resource\$1utilization） 有效统计信息：平均值 单位：百分比  | resource\$1utilization | 
| glue.ALL.memory.non-heap.[available \$1 used] |  指标类别：resource\$1utilization  执行程序的可用/已用非堆内存。ALL 表示所有执行程序。 有效维度：JobName（AWS Glue 作业名称）、JobRunId（JobRun ID 或 ALL）、Type（量规）和 ObservabilityGroup（resource\$1utilization） 有效统计信息：平均值 单位：字节  | resource\$1utilization | 
| glue.ALL.memory.non-heap.used.percentage |  指标类别：resource\$1utilization  执行程序的已用非堆内存（%）。ALL 表示所有执行程序。 有效维度：JobName（AWS Glue 作业名称）、JobRunId（JobRun ID 或 ALL）、Type（量规）和 ObservabilityGroup（resource\$1utilization） 有效统计信息：平均值 单位：百分比  | resource\$1utilization | 
| glue.ALL.memory.total.[available \$1 used] |  指标类别：resource\$1utilization  执行程序的可用/已用总内存。ALL 表示所有执行程序。 有效维度：JobName（AWS Glue 作业名称）、JobRunId（JobRun ID 或 ALL）、Type（量规）和 ObservabilityGroup（resource\$1utilization） 有效统计信息：平均值 单位：字节  | resource\$1utilization | 
| glue.ALL.memory.total.used.percentage |  指标类别：resource\$1utilization  执行程序的已用总内存（%）。ALL 表示所有执行程序。 有效维度：JobName（AWS Glue 作业名称）、JobRunId（JobRun ID 或 ALL）、Type（量规）和 ObservabilityGroup（resource\$1utilization） 有效统计信息：平均值 单位：百分比  | resource\$1utilization | 
| glue.driver.disk.[available\$1GB \$1 used\$1GB] |  指标类别：resource\$1utilization  作业运行期间，驱动程序的可用/已用磁盘空间。这有助于了解磁盘使用趋势，尤其是随时间推移而来的内存使用趋势，从而能帮助避免潜在的故障，此外还可以调试与充足磁盘空间相关的故障。 有效维度：JobName（AWS Glue 作业名称）、JobRunId（JobRun ID 或 ALL）、Type（量规）和 ObservabilityGroup（resource\$1utilization） 有效统计信息：平均值 单位：千兆字节  | resource\$1utilization | 
| glue.driver.disk.used.percentage] |  指标类别：resource\$1utilization  作业运行期间，驱动程序的可用/已用磁盘空间。这有助于了解磁盘使用趋势，尤其是随时间推移而来的内存使用趋势，从而能帮助避免潜在的故障，此外还可以调试与充足磁盘空间相关的故障。 有效维度：JobName（AWS Glue 作业名称）、JobRunId（JobRun ID 或 ALL）、Type（量规）和 ObservabilityGroup（resource\$1utilization） 有效统计信息：平均值 单位：百分比  | resource\$1utilization | 
| glue.ALL.disk.[available\$1GB \$1 used\$1GB] |  指标类别：resource\$1utilization  执行程序的可用/已用磁盘空间。ALL 表示所有执行程序。 有效维度：JobName（AWS Glue 作业名称）、JobRunId（JobRun ID 或 ALL）、Type（量规）和 ObservabilityGroup（resource\$1utilization） 有效统计信息：平均值 单位：千兆字节  | resource\$1utilization | 
| glue.ALL.disk.used.percentage |  指标类别：resource\$1utilization  执行程序的可用/已用/已用（%）磁盘空间。ALL 表示所有执行程序。 有效维度：JobName（AWS Glue 作业名称）、JobRunId（JobRun ID 或 ALL）、Type（量规）和 ObservabilityGroup（resource\$1utilization） 有效统计信息：平均值 单位：百分比  | resource\$1utilization | 
| glue.driver.bytesRead |  指标类别：吞吐量  此作业运行中每个输入源以及所有源读取的字节数。这有助于了解数据量及其随着时间的推移而发生的变化，从而帮助解决诸如数据偏斜之类的问题。 有效维度：JobName（AWS Glue 作业名称）、JobRunId（JobRun ID 或 ALL）、Type（量规）、ObservabilityGroup（resource\$1utilization）和 Source（源数据位置） 有效统计信息：平均值 单位：字节  | 吞吐量 | 
| glue.driver.[recordsRead \$1 filesRead]  |  指标类别：吞吐量  此作业运行中每个输入源以及所有源读取的记录/文件数。这有助于了解数据量及其随着时间的推移而发生的变化，从而帮助解决诸如数据偏斜之类的问题。 有效维度：JobName（AWS Glue 作业名称）、JobRunId（JobRun ID 或 ALL）、Type（量规）、ObservabilityGroup（resource\$1utilization）和 Source（源数据位置） 有效统计信息：平均值 单位：个  | 吞吐量 | 
| glue.driver.partitionsRead  |  指标类别：吞吐量  此作业运行中每个 Amazon S3 输入源以及所有源读取的分区数。 有效维度：JobName（AWS Glue 作业名称）、JobRunId（JobRun ID 或 ALL）、Type（量规）、ObservabilityGroup（resource\$1utilization）和 Source（源数据位置） 有效统计信息：平均值 单位：个  | 吞吐量 | 
| glue.driver.bytesWrittten |  指标类别：吞吐量  此作业运行中每个输出接收器以及所有接收器写入的字节数。这有助于了解数据量及其随着时间的推移而发生的变化，从而帮助解决诸如处理偏斜之类的问题。 有效维度：JobName（AWS Glue 作业名称）、JobRunId（JobRun ID 或 ALL）、Type（量规）、ObservabilityGroup（resource\$1utilization）和 Sink（接收器数据位置） 有效统计信息：平均值 单位：字节  | 吞吐量 | 
| glue.driver.[recordsWritten \$1 filesWritten] |  指标类别：吞吐量  此作业运行中每个输出接收器以及所有接收器写入的记录/文件数。这有助于了解数据量及其随着时间的推移而发生的变化，从而帮助解决诸如处理偏斜之类的问题。 有效维度：JobName（AWS Glue 作业名称）、JobRunId（JobRun ID 或 ALL）、Type（量规）、ObservabilityGroup（resource\$1utilization）和 Sink（接收器数据位置） 有效统计信息：平均值 单位：个  | 吞吐量 | 

## 错误类别
<a name="monitor-observability-error-categories"></a>


| 错误类别 | 说明 | 
| --- | --- | 
| COMPILATION\$1ERROR | 编译 Scala 代码的过程中会出现错误。 | 
| CONNECTION\$1ERROR | 连接到服务/远程主机/数据库服务等过程中会出现错误。 | 
| DISK\$1NO\$1SPACE\$1ERROR |  当驱动程序/执行程序的磁盘中没有剩余空间时，就会出现错误。  | 
| OUT\$1OF\$1MEMORY\$1ERROR | 当驱动程序/执行程序的内存中没有剩余空间时，就会出现错误。 | 
| IMPORT\$1ERROR | 导入依赖项时会出现错误。 | 
| INVALID\$1ARGUMENT\$1ERROR | 如果输入参数无效/非法，则会出现错误。 | 
| PERMISSION\$1ERROR | 当缺乏服务、数据等权限时，就会出现错误。 | 
| RESOURCE\$1NOT\$1FOUND\$1ERROR |  当数据、位置等无法退出时，就会出现错误。  | 
| QUERY\$1ERROR | 执行 Spark SQL 查询时会出现错误。 | 
| SYNTAX\$1ERROR | 当脚本中存在语法错误时，就会出现错误。 | 
| THROTTLING\$1ERROR | 达到服务并发限制或超过服务限额限制时会出现错误。 | 
| DATA\$1LAKE\$1FRAMEWORK\$1ERROR | Hudi、Iceberg 等 AWS Glue 原生支持的数据湖框架出现错误。 | 
| UNSUPPORTED\$1OPERATION\$1ERROR | 进行不支持的操作时会出现错误。 | 
| RESOURCES\$1ALREADY\$1EXISTS\$1ERROR | 创建或添加的资源已存在时会出现错误。 | 
| GLUE\$1INTERNAL\$1SERVICE\$1ERROR | 当出现 AWS Glue 内部服务问题时，就会出现错误。 | 
| GLUE\$1OPERATION\$1TIMEOUT\$1ERROR | AWS Glue 操作超时时会出现错误。 | 
| GLUE\$1VALIDATION\$1ERROR | 当无法验证 AWS Glue 作业的所需值时，就会出现错误。 | 
| GLUE\$1JOB\$1BOOKMARK\$1VERSION\$1MISMATCH\$1ERROR | 当同一作业外显子相同的源存储桶并同时写入相同/不同的目标时会出现错误（并发度 > 1） | 
| LAUNCH\$1ERROR | AWS Glue 作业启动阶段会出现错误。 | 
| DYNAMODB\$1ERROR | 由 Amazon DynamoDB 服务引起的一般错误。 | 
| GLUE\$1ERROR | 由 AWS Glue 服务引起的一般错误。 | 
| LAKEFORMATION\$1ERROR | 由 AWS Lake Formation 服务引起的一般错误。 | 
| REDSHIFT\$1ERROR | 由 Amazon Redshift 服务引起的一般错误。 | 
| S3\$1ERROR | 由 Amazon S3 服务引起的一般错误。 | 
| SYSTEM\$1EXIT\$1ERROR | 通用系统退出错误。 | 
| TIMEOUT\$1ERROR | 当作业因操作超时而失败时，就会出现一般错误。 | 
| UNCLASSIFIED\$1SPARK\$1ERROR | 由 Spark 引起的一般错误。 | 
| UNCLASSIFIED\$1ERROR | 默认错误类别。 | 

## 限制
<a name="monitoring-observability-limitations"></a>

**注意**  
`glueContext` 必须初始化才能发布指标。

 在源维度中，该值可以是 Amazon S3 路径或表名，具体视源类型而定。此外，如果源为 JDBC 并且使用了查询选项，则会在源维度中设置查询字符串。如果该值超过 500 个字符，则将其修剪为 500 个字符以内。以下是该值的限制：
+ 将删除非 ASCII 字符。
+ 如果源名称不包含任何 ASCII 字符，则会将其转换为 <非 ASCII 输入>。

### 吞吐量指标限制和注意事项
<a name="monitoring-observability-considerations"></a>
+  支持 DataFrame 和基于 DataFrame 的 DynamicFrame（例如 JDBC，在 Amazon S3 上从 parquet 读取），但不支持基于 RDD 的 DynamicFrame（例如在 Amazon S3 上读取 csv、json 等）。从技术上讲，支持 Spark UI 上显示的所有读取和写入。
+  如果数据来源为目录表且格式为 JSON、CSV、文本或 Iceberg，将发出 `recordsRead` 指标。
+  JDBC 和 Iceberg 表中没有 `glue.driver.throughput.recordsWritten`、`glue.driver.throughput.bytesWritten` 和 `glue.driver.throughput.filesWritten` 指标。
+  指标可能会延迟。如果作业在大约一分钟后完成，则 Amazon CloudWatch 指标中可能没有吞吐量指标。

# 作业监控和调试
<a name="monitor-profile-glue-job-cloudwatch-metrics"></a>

您可以收集有关 AWS Glue 任务的指标，并在 AWS Glue 和 Amazon CloudWatch 控制台上显示它们，以确定并修复问题。分析 AWS Glue 作业需要执行以下步骤：

1.  启用指标：

   1.  在作业定义中启用 **Job metrics (作业指标)** 选项。您可以在 AWS Glue 控制台中启用分析，也可以作为作业的参数。有关更多信息，请参阅[定义 Spark 作业的作业属性](add-job.md#create-job)或[在 AWS Glue 作业中使用作业参数](aws-glue-programming-etl-glue-arguments.md)。

   1.  在作业定义中启用 **AWS Glue 可观测性指标**选项。您可以在 AWS Glue 控制台中启用可观测性，也可以作为作业的参数。有关更多信息，请参阅 [使用 AWS Glue 可观测性指标进行监控](monitor-observability.md)。

1. 确认作业脚本初始化 `GlueContext`。例如，以下脚本代码段初始化 `GlueContext` 并显示在脚本中放置已分析代码的位置。此常规格式用于后续的调试方案。

   ```
   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
   import time
   
   ## @params: [JOB_NAME]
   args = getResolvedOptions(sys.argv, ['JOB_NAME'])
   
   sc = SparkContext()
   glueContext = GlueContext(sc)
   spark = glueContext.spark_session
   job = Job(glueContext)
   job.init(args['JOB_NAME'], args)
   
   ...
   ...
   code-to-profile
   ...
   ...
   
   
   job.commit()
   ```

1. 运行作业。

1. 可视化指标：

   1. 在 AWS Glue 控制台上显示作业指标，并确定驱动程序或执行程序的异常指标。

   1. 在作业运行监测页面、作业运行详细信息页面或 Amazon CloudWatch 上查看可观测性指标。有关更多信息，请参阅 [使用 AWS Glue 可观测性指标进行监控](monitor-observability.md)。

1. 使用已确定的指标缩小根本原因范围。

1. 也可以选择使用已确定驱动程序或作业执行程序的日志流确认根本原因。

 **AWS Glue 可观测性指标的用例** 
+  [调试 OOM 异常和作业异常](monitor-profile-debug-oom-abnormalities.md) 
+  [调试要求苛刻的阶段和落后任务](monitor-profile-debug-straggler.md) 
+  [监控多个作业的进度](monitor-debug-multiple.md) 
+  [监控 DPU 容量规划](monitor-debug-capacity.md) 
+  [使用 AWS Glue 可观测性监测资源利用率以降低成本](https://aws.amazon.com/blogs/big-data/enhance-monitoring-and-debugging-for-aws-glue-jobs-using-new-job-observability-metrics) 

# 调试 OOM 异常和作业异常
<a name="monitor-profile-debug-oom-abnormalities"></a>

您可以在 AWS Glue 中调试内存不足 (OOM) 异常和作业异常。以下部分介绍用于调试 Apache Spark 驱动程序或 Spark 执行程序的内存不足异常的方案。
+ [调试驱动程序 OOM 异常](#monitor-profile-debug-oom-driver)
+ [调试执行程序 OOM 异常](#monitor-profile-debug-oom-executor)

## 调试驱动程序 OOM 异常
<a name="monitor-profile-debug-oom-driver"></a>

在这种情况下，Spark 任务从 Amazon Simple Storage Service（Amazon S3）中读取大量小文件。它会将这些文件转换为 Apache Parquet 格式，然后将其写出到 Amazon S3。Spark 驱动程序内存不足。输入 Amazon S3 数据在各 Amazon S3 分区中的文件数量已超过 100 万个。

配置的代码如下所示：

```
data = spark.read.format("json").option("inferSchema", False).load("s3://input_path")
data.write.format("parquet").save(output_path)
```

### 在 AWS Glue 控制台上可视化分析指标
<a name="monitor-debug-oom-visualize"></a>

下图显示了以驱动程序和执行程序的百分比表示的内存使用率。此使用率绘制为一个数据点，它是上一分钟报告的值的平均数。您可以在作业的内存配置文件中看到[驱动程序内存](monitoring-awsglue-with-cloudwatch-metrics.md#glue.driver.jvm.heap.usage)快速超过 50% 使用率的安全阈值。另一方面，所有执行程序的[平均内存使用率](monitoring-awsglue-with-cloudwatch-metrics.md#glue.ALL.jvm.heap.usage)仍低于 4%。这清楚地显示了此 Spark 作业中驱动程序执行的异常。

![\[驱动程序和执行程序的内存使用率百分比。\]](http://docs.aws.amazon.com/zh_cn/glue/latest/dg/images/monitor-debug-oom-memoryprofile.png)


该作业运行很快失败，并在 ** 控制台上的**历史记录AWS Glue选项卡中出现以下错误：Command Failed with Exit Code 1 (命令失败，退出代码 1)。此错误字符串表示任务由于系统错误而失败 – 在此示例中，该错误为驱动程序内存不足。

![\[此错误消息显示在 AWS Glue 控制台上。\]](http://docs.aws.amazon.com/zh_cn/glue/latest/dg/images/monitor-debug-oom-errorstring.png)


在控制台上，选择 **History (历史记录)** 选项卡上的 **Error logs (错误日志)** 链接以确认 CloudWatch Logs 中有关驱动程序 OOM 的查找结果。在作业的错误日志中搜索“**Error**”以确认确实是 OOM 异常使作业失败：

```
# java.lang.OutOfMemoryError: Java heap space
# -XX:OnOutOfMemoryError="kill -9 %p"
# Executing /bin/sh -c "kill -9 12039"...
```

在作业的**历史记录**选项卡上，选择**日志**。您可以在任务开始时在 CloudWatch Logs 中找到驱动程序执行的以下跟踪。Spark 驱动程序尝试列出所有目录中的所有文件，构造 `InMemoryFileIndex`，并为每个文件启动一个任务。这进而会导致 Spark 驱动程序必须在内存中维持大量状态以跟踪所有任务。它会缓存内存索引的大量文件的完整列表，从而导致驱动程序 OOM。

### 使用分组修复多个文件的处理
<a name="monitor-debug-oom-fix"></a>

您可以通过使用 *. 中的*分组AWS Glue 功能修复多个文件的处理。使用动态帧时以及输入数据集包含大量文件（超过 50,000 个）时，将自动启用分组功能。分组使您可以将多个文件合并到一个组中，并且允许任务处理整个组而非单个文件。因此，Spark 驱动程序在内存中存储显著减少的状态以跟踪较少的任务。有关手动为数据集启用分组的更多信息，请参阅[以较大的组读取输入文件](grouping-input-files.md)。

要检查 AWS Glue 作业的内存配置文件，请在启用分组的情况下配置以下代码：

```
df = glueContext.create_dynamic_frame_from_options("s3", {'paths': ["s3://input_path"], "recurse":True, 'groupFiles': 'inPartition'}, format="json")
datasink = glueContext.write_dynamic_frame.from_options(frame = df, connection_type = "s3", connection_options = {"path": output_path}, format = "parquet", transformation_ctx = "datasink")
```

您可以在 AWS Glue 作业配置文件中监控内存配置文件和 ETL 数据移动。

在 AWS Glue 任务的整个持续时间内，驱动程序在低于 50% 内存使用率的阈值下运行。执行程序从 Amazon S3 流式传输数据，对其进行处理，然后将其写出到 Amazon S3。因此，它们在任何时间点消耗的内存不到 5%。

![\[显示问题的内存配置文件已得到修复。\]](http://docs.aws.amazon.com/zh_cn/glue/latest/dg/images/monitor-debug-oom-memoryprofile-fixed.png)


下面的数据移动配置文件显示了任务进行时所有执行程序在最后一分钟内[读取](monitoring-awsglue-with-cloudwatch-metrics.md#glue.ALL.s3.filesystem.read_bytes)和[写入](monitoring-awsglue-with-cloudwatch-metrics.md#glue.ALL.s3.filesystem.write_bytes)的 Amazon S3 字节总数。两者当数据在所有执行程序中流式传输时都遵循类似的模式。该作业在不到三个小时内完成处理所有一百万个文件。

![\[显示问题的数据移动配置文件已得到修复。\]](http://docs.aws.amazon.com/zh_cn/glue/latest/dg/images/monitor-debug-oom-etlmovement.png)


## 调试执行程序 OOM 异常
<a name="monitor-profile-debug-oom-executor"></a>

在此方案中，您可以了解如何调试 Apache Spark 执行程序中可能出现的 OOM 异常。以下代码使用 Spark 的 MySQL 读取器将大约 3400 万行的一个大型表读入 Spark 数据帧中。然后它以 Parquet 格式将其写出到 Amazon S3。您可以提供连接属性，并使用默认 Spark 配置来读取表。

```
val connectionProperties = new Properties()
connectionProperties.put("user", user)
connectionProperties.put("password", password)
connectionProperties.put("Driver", "com.mysql.jdbc.Driver")
val sparkSession = glueContext.sparkSession
val dfSpark = sparkSession.read.jdbc(url, tableName, connectionProperties)
dfSpark.write.format("parquet").save(output_path)
```

### 在 AWS Glue 控制台上可视化分析指标
<a name="monitor-debug-oom-visualize-2"></a>

如果内存使用情况图的斜率为正且超过 50%，则如果作业在发出下一个衡量指标之前失败，那么内存耗尽是一个很好的候选原因。下图显示了在执行的一分钟内，所有执行程序的[平均内存使用率](monitoring-awsglue-with-cloudwatch-metrics.md#glue.ALL.jvm.heap.usage)快速超过 50%。使用率高达 92%，而且运行执行程序的容器被 Apache Hadoop YARN 停止。

![\[所有执行程序的平均内存使用率。\]](http://docs.aws.amazon.com/zh_cn/glue/latest/dg/images/monitor-debug-oom-2-memoryprofile.png)


如下图所示，在作业失败之前始终会有[单个执行程序](monitoring-awsglue-with-cloudwatch-metrics.md#glue.driver.ExecutorAllocationManager.executors.numberAllExecutors)在运行。这是因为启动了新的执行程序以替换停止的执行程序。默认情况下，不会并行读取 JDBC 数据源，因为它需要对表中的列进行分区并打开多个连接。因此，只有一个执行程序按顺序读入整个表。

![\[作业执行显示在作业失败之前单个执行程序在运行。\]](http://docs.aws.amazon.com/zh_cn/glue/latest/dg/images/monitor-debug-oom-2-execution.png)


如下图所示，Spark 尝试在作业失败之前四次启动新任务。您可以看到三个执行程序的[内存配置文件](monitoring-awsglue-with-cloudwatch-metrics.md#glue.ALL.jvm.heap.used)。每个执行程序都会快速耗尽其所有内存。第四个执行程序内存不足，作业失败。因此，不会立即报告其指标。

![\[执行程序的内存配置文件。\]](http://docs.aws.amazon.com/zh_cn/glue/latest/dg/images/monitor-debug-oom-2-exec-memprofile.png)


您可以从 AWS Glue 控制台上的错误字符串确认作业因 OOM 异常而失败，如下图所示。

![\[此错误消息显示在 AWS Glue 控制台上。\]](http://docs.aws.amazon.com/zh_cn/glue/latest/dg/images/monitor-debug-oom-2-errorstring.png)


**任务输出日志：**要进一步确认执行程序 OOM 异常这一发现，请查看 CloudWatch Logs。当您搜索 **Error** 时，您会发现四个执行程序在指标控制面板上显示的大致相同的时间段内被停止。所有执行程序均被 YARN 终止，因为它们超出其内存限制。

执行程序 1

```
18/06/13 16:54:29 WARN YarnAllocator: Container killed by YARN for exceeding memory limits. 5.5 GB of 5.5 GB physical memory used. Consider boosting spark.yarn.executor.memoryOverhead.
18/06/13 16:54:29 WARN YarnSchedulerBackend$YarnSchedulerEndpoint: Container killed by YARN for exceeding memory limits. 5.5 GB of 5.5 GB physical memory used. Consider boosting spark.yarn.executor.memoryOverhead.
18/06/13 16:54:29 ERROR YarnClusterScheduler: Lost executor 1 on ip-10-1-2-175.ec2.internal: Container killed by YARN for exceeding memory limits. 5.5 GB of 5.5 GB physical memory used. Consider boosting spark.yarn.executor.memoryOverhead.
18/06/13 16:54:29 WARN TaskSetManager: Lost task 0.0 in stage 0.0 (TID 0, ip-10-1-2-175.ec2.internal, executor 1): ExecutorLostFailure (executor 1 exited caused by one of the running tasks) Reason: Container killed by YARN for exceeding memory limits. 5.5 GB of 5.5 GB physical memory used. Consider boosting spark.yarn.executor.memoryOverhead.
```

执行程序 2

```
18/06/13 16:55:35 WARN YarnAllocator: Container killed by YARN for exceeding memory limits. 5.8 GB of 5.5 GB physical memory used. Consider boosting spark.yarn.executor.memoryOverhead.
18/06/13 16:55:35 WARN YarnSchedulerBackend$YarnSchedulerEndpoint: Container killed by YARN for exceeding memory limits. 5.8 GB of 5.5 GB physical memory used. Consider boosting spark.yarn.executor.memoryOverhead.
18/06/13 16:55:35 ERROR YarnClusterScheduler: Lost executor 2 on ip-10-1-2-16.ec2.internal: Container killed by YARN for exceeding memory limits. 5.8 GB of 5.5 GB physical memory used. Consider boosting spark.yarn.executor.memoryOverhead.
18/06/13 16:55:35 WARN TaskSetManager: Lost task 0.1 in stage 0.0 (TID 1, ip-10-1-2-16.ec2.internal, executor 2): ExecutorLostFailure (executor 2 exited caused by one of the running tasks) Reason: Container killed by YARN for exceeding memory limits. 5.8 GB of 5.5 GB physical memory used. Consider boosting spark.yarn.executor.memoryOverhead.
```

执行程序 3

```
18/06/13 16:56:37 WARN YarnAllocator: Container killed by YARN for exceeding memory limits. 5.8 GB of 5.5 GB physical memory used. Consider boosting spark.yarn.executor.memoryOverhead.
18/06/13 16:56:37 WARN YarnSchedulerBackend$YarnSchedulerEndpoint: Container killed by YARN for exceeding memory limits. 5.8 GB of 5.5 GB physical memory used. Consider boosting spark.yarn.executor.memoryOverhead.
18/06/13 16:56:37 ERROR YarnClusterScheduler: Lost executor 3 on ip-10-1-2-189.ec2.internal: Container killed by YARN for exceeding memory limits. 5.8 GB of 5.5 GB physical memory used. Consider boosting spark.yarn.executor.memoryOverhead.
18/06/13 16:56:37 WARN TaskSetManager: Lost task 0.2 in stage 0.0 (TID 2, ip-10-1-2-189.ec2.internal, executor 3): ExecutorLostFailure (executor 3 exited caused by one of the running tasks) Reason: Container killed by YARN for exceeding memory limits. 5.8 GB of 5.5 GB physical memory used. Consider boosting spark.yarn.executor.memoryOverhead.
```

执行程序 4

```
18/06/13 16:57:18 WARN YarnAllocator: Container killed by YARN for exceeding memory limits. 5.5 GB of 5.5 GB physical memory used. Consider boosting spark.yarn.executor.memoryOverhead.
18/06/13 16:57:18 WARN YarnSchedulerBackend$YarnSchedulerEndpoint: Container killed by YARN for exceeding memory limits. 5.5 GB of 5.5 GB physical memory used. Consider boosting spark.yarn.executor.memoryOverhead.
18/06/13 16:57:18 ERROR YarnClusterScheduler: Lost executor 4 on ip-10-1-2-96.ec2.internal: Container killed by YARN for exceeding memory limits. 5.5 GB of 5.5 GB physical memory used. Consider boosting spark.yarn.executor.memoryOverhead.
18/06/13 16:57:18 WARN TaskSetManager: Lost task 0.3 in stage 0.0 (TID 3, ip-10-1-2-96.ec2.internal, executor 4): ExecutorLostFailure (executor 4 exited caused by one of the running tasks) Reason: Container killed by YARN for exceeding memory limits. 5.5 GB of 5.5 GB physical memory used. Consider boosting spark.yarn.executor.memoryOverhead.
```

### 使用 AWS Glue 动态帧修复提取大小设置
<a name="monitor-debug-oom-fix-2"></a>

执行程序在读取 JDBC 表时内存不足，因为 Spark JDBC 提取大小的默认配置为零。这意味着 Spark 执行程序上的 JDBC 驱动程序尝试从数据库中一起提取 3400 万行并对其进行缓存，即使 Spark 一次流式传输一行。使用 Spark，您可以通过将提取大小参数设置为非零默认值来避免此情况。

您还可以通过使用 AWS Glue 动态帧修复此问题。默认情况下，动态帧使用 1000 行的提取大小，这通常是一个足够的值。因此，执行程序不会占用其总内存的 7% 以上。AWS Glue 作业只需单个执行程序即可在不到两分钟内完成。虽然建议的方法是使用 AWS Glue 动态帧，但也可以使用 Apache Spark `fetchsize` 属性设置提取大小。请参阅 [Spark SQL、DataFrame 和 Dataset 指南](https://spark.apache.org/docs/2.2.0/sql-programming-guide.html#jdbc-to-other-databases)。

```
val (url, database, tableName) = {
 ("jdbc_url", "db_name", "table_name")
 } 
val source = glueContext.getSource(format, sourceJson)
val df = source.getDynamicFrame
glueContext.write_dynamic_frame.from_options(frame = df, connection_type = "s3", connection_options = {"path": output_path}, format = "parquet", transformation_ctx = "datasink")
```

**正常的分析指标：**具有 [ 动态帧的](monitoring-awsglue-with-cloudwatch-metrics.md#glue.ALL.jvm.heap.usage)执行程序内存AWS Glue永远不会超过安全阈值，如下图所示。它在数据库的行中流式传输数据，并且在任何时间点在 JDBC 驱动程序中仅缓存 1,000 行。不会发生内存不足异常。

![\[AWS Glue 控制台显示执行程序内存低于安全阈值。\]](http://docs.aws.amazon.com/zh_cn/glue/latest/dg/images/monitor-debug-oom-2-memoryprofile-fixed.png)


# 调试要求苛刻的阶段和落后任务
<a name="monitor-profile-debug-straggler"></a>

您可以使用 AWS Glue 作业分析来确定提取、转换和加载 (ETL) 作业中要求苛刻的阶段和落后任务。在 AWS Glue 作业的某个阶段，落后任务比其余任务需要更长的时间。因此，该阶段需要更长的时间才能完成，这也会延迟作业的总执行时间。

## 将小型输入文件合并为更大的输出文件
<a name="monitor-profile-debug-straggler-scenario-1"></a>

当不同任务中的工作分配不均衡时，可能会出现落后任务，或者数据倾斜会导致一个任务处理更多数据。

您可以分析以下代码 – Apache Spark 中的一种常见模式 – 以将大量小文件合并为更大的输出文件。在本示例中，输入数据集为 32 GB 的 JSON Gzip 压缩文件。输出数据集包含大约 190 GB 的未压缩 JSON 文件。

配置的代码如下所示：

```
datasource0 = spark.read.format("json").load("s3://input_path")
df = datasource0.coalesce(1)
df.write.format("json").save(output_path)
```

### 在 AWS Glue 控制台上可视化分析指标
<a name="monitor-debug-straggler-visualize"></a>

您可以分析您的作业以检查四组不同的指标：
+ ETL 数据移动
+ 执行程序之间的数据随机排序
+ 任务执行
+ 内存配置文件

**ETL 数据移动**：在 **ETL 数据移动**配置文件中，在前六分钟内完成的第一阶段中的所有执行程序都会相当快速地[读取](monitoring-awsglue-with-cloudwatch-metrics.md#glue.ALL.s3.filesystem.read_bytes)字节。但是，总作业执行时间大约为一小时，主要由数据[写入](monitoring-awsglue-with-cloudwatch-metrics.md#glue.ALL.s3.filesystem.write_bytes)时间组成。

![\[显示 ETL 数据移动配置文件的图表。\]](http://docs.aws.amazon.com/zh_cn/glue/latest/dg/images/monitor-debug-straggler-1.png)


**执行程序之间的数据随机排序：**随机排序期间[读取](monitoring-awsglue-with-cloudwatch-metrics.md#glue.driver.aggregate.shuffleLocalBytesRead)和[写入](monitoring-awsglue-with-cloudwatch-metrics.md#glue.driver.aggregate.shuffleBytesWritten)的字节数还在阶段 2 结束之前显示一个峰值，如**Job Execution (作业执行)** 和**Data Shuffle (数据随机排序)** 指标所示。在从所有执行程序对数据进行随机排序之后，读取和写入仅从 3 号执行程序继续。

![\[执行程序之间的数据随机排序指标。\]](http://docs.aws.amazon.com/zh_cn/glue/latest/dg/images/monitor-debug-straggler-2.png)


**作业执行：**如下图所示，所有其他执行程序均处于空闲状态，并最终在 10:09 之前被释放。此时，执行程序的总数减少到只有一个。这显然表明 3 号执行程序由执行时间最长并且占据大部分作业执行时间的落后任务组成。

![\[活动执行程序的执行指标。\]](http://docs.aws.amazon.com/zh_cn/glue/latest/dg/images/monitor-debug-straggler-3.png)


**内存配置文件：**在前两个阶段之后，只有 [3 号执行程序](monitoring-awsglue-with-cloudwatch-metrics.md#glue.executorId.jvm.heap.used)在主动消耗内存来处理数据。其余执行程序只是处于空闲状态或在前两个阶段完成后很快被释放。

![\[前两个阶段之后内存配置文件的指标。\]](http://docs.aws.amazon.com/zh_cn/glue/latest/dg/images/monitor-debug-straggler-4.png)


### 使用分组修复落后的执行程序
<a name="monitor-debug-straggler-fix"></a>

您可以通过使用 * 中的*分组AWS Glue功能来避免执行程序落后。使用分组在所有执行程序中均匀分配数据，并使用集群上的所有可用执行程序将文件合并为更大的文件。有关更多信息，请参阅 [以较大的组读取输入文件](grouping-input-files.md)。

要检查 AWS Glue 作业中的 ETL 数据移动，请在启用分组的情况下配置以下代码：

```
df = glueContext.create_dynamic_frame_from_options("s3", {'paths': ["s3://input_path"], "recurse":True, 'groupFiles': 'inPartition'}, format="json")
datasink = glueContext.write_dynamic_frame.from_options(frame = df, connection_type = "s3", connection_options = {"path": output_path}, format = "json", transformation_ctx = "datasink4")
```

**ETL 数据移动：**整个作业执行时间内的数据写入与数据读取现在并行进行流式传输。因此，任务在八分钟内完成 – 比以前快得多。

![\[显示问题已得到修复的 ETL 数据移动。\]](http://docs.aws.amazon.com/zh_cn/glue/latest/dg/images/monitor-debug-straggler-5.png)


**执行程序之间的数据随机排序：**由于输入文件在读取期间使用分组功能进行了合并，因此在读取数据后不会进行代价高昂的数据随机排序。

![\[显示问题已得到修复的数据随机排序指标。\]](http://docs.aws.amazon.com/zh_cn/glue/latest/dg/images/monitor-debug-straggler-6.png)


**作业执行：**作业执行指标显示运行和处理数据的活动执行程序总数保持恒定。作业中没有单个落后者。所有执行程序均处于活动状态，在完成作业之前不会被释放。由于执行程序中没有数据的中间随机排序情况，因此作业中只有一个阶段。

![\[作业执行小部件的指标显示作业中没有出现落后者。\]](http://docs.aws.amazon.com/zh_cn/glue/latest/dg/images/monitor-debug-straggler-7.png)


**内存配置文件：**相关指标显示所有执行程序的[活动内存消耗](monitoring-awsglue-with-cloudwatch-metrics.md#glue.executorId.jvm.heap.used) – 跨所有执行程序重新确认存在活动。随着数据并行流入和写出，所有执行程序的总内存占用空间大致均匀，远低于所有执行程序的安全阈值。

![\[显示所有执行程序的活动内存消耗的内存配置文件指标。\]](http://docs.aws.amazon.com/zh_cn/glue/latest/dg/images/monitor-debug-straggler-8.png)


# 监控多个作业的进度
<a name="monitor-debug-multiple"></a>

您可以一起分析多个 AWS Glue 作业并监控它们之间的数据流。这是一种常见的工作流模式，需要监控单个作业进度、数据处理积压、数据重新处理和作业书签。

**Topics**
+ [分析代码](#monitor-debug-multiple-profile)
+ [在 AWS Glue 控制台上可视化分析指标](#monitor-debug-multiple-visualize)
+ [修复文件的处理](#monitor-debug-multiple-fix)

## 分析代码
<a name="monitor-debug-multiple-profile"></a>

在此工作流程中，您有两个作业：一个输入作业和一个输出作业。输入作业计划使用定期触发器每 30 分钟运行一次。输出作业计划在每次成功运行输入作业后运行。可使用作业触发器控制这些计划作业。

![\[显示控制输入和输出作业计划的作业触发器的控制台屏幕截图。\]](http://docs.aws.amazon.com/zh_cn/glue/latest/dg/images/monitor-debug-multiple-1.png)


**输入任务**：此任务从 Amazon Simple Storage Service（Amazon S3）位置读取数据，使用 `ApplyMapping` 对数据进行转换，并将其写入暂存的 Amazon S3 位置。以下代码是输入作业的分析代码：

```
datasource0 = glueContext.create_dynamic_frame.from_options(connection_type="s3", connection_options = {"paths": ["s3://input_path"], "useS3ListImplementation":True,"recurse":True}, format="json")
applymapping1 = ApplyMapping.apply(frame = datasource0, mappings = [map_spec])
datasink2 = glueContext.write_dynamic_frame.from_options(frame = applymapping1, connection_type = "s3", connection_options = {"path": staging_path, "compression": "gzip"}, format = "json")
```

**输出任务**：此任务从 Amazon S3 中的暂存位置读取输入任务的输出，再次对其进行转换，并将其写入目标位置：

```
datasource0 = glueContext.create_dynamic_frame.from_options(connection_type="s3", connection_options = {"paths": [staging_path], "useS3ListImplementation":True,"recurse":True}, format="json")
applymapping1 = ApplyMapping.apply(frame = datasource0, mappings = [map_spec])
datasink2 = glueContext.write_dynamic_frame.from_options(frame = applymapping1, connection_type = "s3", connection_options = {"path": output_path}, format = "json")
```

## 在 AWS Glue 控制台上可视化分析指标
<a name="monitor-debug-multiple-visualize"></a>

以下控制面板将输入任务中的 Amazon S3 字节写入指标叠加到输出任务的同一时间表的 Amazon S3 字节读取指标上。时间表显示输入和输出作业的不同作业运行。输入作业（以红色显示）每 30 分钟启动一次。输出作业（以棕色显示）在输入作业完成时启动，最大并发数为 1。

![\[显示读取和写入数据的图表。\]](http://docs.aws.amazon.com/zh_cn/glue/latest/dg/images/monitor-debug-multiple-4.png)


在本示例中，未启用[作业书签](https://docs.aws.amazon.com/glue/latest/dg/monitor-continuations.html)。没有用于在脚本代码中启用作业书签的转换上下文。

**作业历史记录**：输入和输出作业具有多个从中午 12:00 启动的作业运行，如**历史记录**选项卡上所示。

AWS Glue 控制台上的输入任务如下所示：

![\[显示输入作业的“历史记录”选项卡的控制台屏幕截图。\]](http://docs.aws.amazon.com/zh_cn/glue/latest/dg/images/monitor-debug-multiple-2.png)


下图显示了输出作业：

![\[显示输出作业的“历史记录”选项卡的控制台屏幕截图。\]](http://docs.aws.amazon.com/zh_cn/glue/latest/dg/images/monitor-debug-multiple-3.png)


**第一次作业运行**：如下面的数据字节读取和写入图表所示，在 12:00 到 12:30 之间的输入和输出作业的第一次作业运行显示曲线下大致相同的区域。这些区域表示由输入任务写入的 Amazon S3 字节和由输出任务读取的 Amazon S3 字节。此数据同样通过写入的 Amazon S3 字节的比率（总计超过 30 分钟 – 输入任务的任务触发频率）来确认。中午 12:00 启动的输入作业运行的比率的数据点也是 1。

下图显示了所有作业运行的数据流比率：

![\[显示数据流比率的图表：写入的字节数和读取的字节数。\]](http://docs.aws.amazon.com/zh_cn/glue/latest/dg/images/monitor-debug-multiple-5.png)


**第二次作业运行**：在第二次作业运行中，输出作业读取的字节数与输入作业写入的字节数相比明显不同。（比较输出作业的两次作业运行的曲线下的区域，或比较输入和输出作业的第二次运行中的区域。） 读取和写入的字节比率表明，在 12:30 到 13:00 的第二个 30 分钟跨度内，输出作业读取的数据约为输入作业写入的数据的 2.5 倍。这是因为由于未启用作业书签，导致输出作业重新处理了输入作业的第一次作业运行的输出。比率大于 1 表示输出作业处理的数据存在额外的积压。

**第三次作业运行**：输入作业在写入的字节数方面相当一致（请参阅红色曲线下的区域）。但是，输入作业的第三次作业运行时间比预期的要长（请参阅红色曲线的长尾）。因此，输出作业的第三次作业运行启动较晚。第三次作业运行在 13:00 到 13:30 之间的剩余 30 分钟内仅处理了暂存位置中累积的一小部分数据。字节流的比率表明，它仅处理了由输入作业的第三次作业运行写入的 0.83 数据（请参阅 13:00 的比率）。

**重叠的输入和输出作业**：输入作业的第四次作业运行按照计划在输出作业的第三次作业运行完成之前于 13:30 启动。这两次作业运行之间存在部分重叠。但是，输出任务的第三次任务运行仅捕获它于 13:17 左右启动时在 Amazon S3 的暂存位置列出的文件。这包括输入作业的第一次作业运行的所有数据输出。13:30 的实际比率约为 2.75。输出作业的第三次作业运行处理了输入作业的第四次作业运行从 13:30 到 14:00 写入的大约 2.75 倍数据。

如这些图像所示，输出作业正在从输入作业的所有先前作业运行中的暂存位置重新处理数据。因此，输出作业的第四次作业运行时间最长，并与输入作业的整个第五次作业运行重叠。

## 修复文件的处理
<a name="monitor-debug-multiple-fix"></a>

您应确保输出作业仅处理输出作业的先前作业运行尚未处理的文件。为此，请启用作业书签并在输出作业中设置转换上下文，如下所示：

```
datasource0 = glueContext.create_dynamic_frame.from_options(connection_type="s3", connection_options = {"paths": [staging_path], "useS3ListImplementation":True,"recurse":True}, format="json", transformation_ctx = "bookmark_ctx")
```

启用作业书签后，输出作业不会重新处理输入作业的所有先前作业运行的暂存位置中的数据。在显示读取和写入数据的下图中，棕色曲线下的区域相当一致，并与红色曲线类似。

![\[将读取和写入数据显示为红色和棕色线条的图表。\]](http://docs.aws.amazon.com/zh_cn/glue/latest/dg/images/monitor-debug-multiple-6.png)


字节流的比率还保持大致接近 1，因为没有处理其他数据。

![\[显示数据流比率的图表：写入的字节数和读取的字节数\]](http://docs.aws.amazon.com/zh_cn/glue/latest/dg/images/monitor-debug-multiple-7.png)


在下一次输入作业运行开始将更多数据放入暂存位置之前，输出作业的作业运行将启动并捕获暂存位置中的文件。只要它继续执行此操作，就会仅处理从先前输入作业运行中捕获的文件，并且该比率保持接近 1。

![\[显示数据流比率的图表：写入的字节数和读取的字节数\]](http://docs.aws.amazon.com/zh_cn/glue/latest/dg/images/monitor-debug-multiple-7.png)


假设输入作业花费的时间超过预期，那么，输出作业将从两次输入作业运行中捕获暂存位置中的文件。该输出作业运行的比率将大于 1。但是，输出作业的以下作业运行不会处理已由输出作业的先前作业运行处理的任何文件。

# 监控 DPU 容量规划
<a name="monitor-debug-capacity"></a>

您可以使用 AWS Glue 中的作业指标估算可用于扩展 AWS Glue 作业的数据处理单元 (DPU) 的数量。

**注意**  
此页面仅适用于 AWS Glue 0.9 和 1.0 版。最新版本的 AWS Glue 包含成本节省功能，介绍了在进行容量规划时的其他注意事项。

**Topics**
+ [分析代码](#monitor-debug-capacity-profile)
+ [在 AWS Glue 控制台上可视化分析指标](#monitor-debug-capacity-visualize)
+ [确定最佳 DPU 容量](#monitor-debug-capacity-fix)

## 分析代码
<a name="monitor-debug-capacity-profile"></a>

以下脚本读取包含 428 个 gzip 类型 JSON 文件的 Amazon Simple Storage Service（Amazon S3）分区。该脚本应用映射来更改字段名称，以 Apache Parquet 格式转换这些名称并将其写入 Amazon S3。您可以按默认值预置 10 个 DPU 并运行此任务。

```
datasource0 = glueContext.create_dynamic_frame.from_options(connection_type="s3", connection_options = {"paths": [input_path], "useS3ListImplementation":True,"recurse":True}, format="json")
applymapping1 = ApplyMapping.apply(frame = datasource0, mappings = [(map_spec])
datasink2 = glueContext.write_dynamic_frame.from_options(frame = applymapping1, connection_type = "s3", connection_options = {"path": output_path}, format = "parquet")
```

## 在 AWS Glue 控制台上可视化分析指标
<a name="monitor-debug-capacity-visualize"></a>

**作业运行 1：**在此作业运行中，我们将展示如何确定集群中是否存在预配置不足的 DPU。AWS Glue 中的作业执行功能显示[主动运行的执行程序的总数](monitoring-awsglue-with-cloudwatch-metrics.md#glue.driver.ExecutorAllocationManager.executors.numberAllExecutors)、[已完成的阶段数](monitoring-awsglue-with-cloudwatch-metrics.md#glue.driver.aggregate.numCompletedStages)和[所需的最大执行程序数](monitoring-awsglue-with-cloudwatch-metrics.md#glue.driver.ExecutorAllocationManager.executors.numberMaxNeededExecutors)。

通过添加正在运行的任务和待处理任务的总数，并将其除以每个执行程序的任务数来计算所需的最大执行程序数。此结果衡量满足当前负载所需的执行程序总数。

相反，主动运行的执行程序的数量衡量运行活动 Apache Spark 任务的执行程序数量。随着作业的运行，所需的最大执行程序数可能发生变化，并且通常会在待处理任务队列减少时向下移动到作业的末尾。

下图中的水平红线显示了最大已分配执行程序数，这取决于您为作业分配的 DPU 数。在此案例中，您为作业运行分配 10 个 DPU。为管理预留一个 DPU。其他九个 DPU 各自运行两个执行程序，并为 Spark 驱动程序保留一个执行程序。Spark 驱动程序在主应用程序内部运行。因此，最大已分配执行程序数为 2\$19 - 1 = 17 个执行程序。

![\[显示活动执行程序和最大所需执行程序的作业指标。\]](http://docs.aws.amazon.com/zh_cn/glue/latest/dg/images/monitor-debug-capacity-1.png)


如图所示，所需的最大执行程序数在作业开始时从 107 开始，而活动执行程序数保持为 17。这与具有 10 个 DPU 的最大已分配执行程序数相同。所需的最大执行程序数和最大已分配执行程序数之间的比率（对于 Spark 驱动程序，两者都加 1）会为您提供预配置不足系数：108/18 = 6x。您可以预置 6（在配置比率下）\$1 9（当前 DPU 容量 - 1）\$1 1 个 DPU = 55 个 DPU 来扩展作业，以最大并行度运行它并更快地完成。

AWS Glue 控制台将详细的作业指标显示为表示原始最大已分配执行程序数的静态行。控制台从指标的作业定义计算最大已分配执行程序数。相比这下，对于详细的作业运行指标，控制台从作业运行配置计算最大已分配执行程序数，特别是为作业运行分配的 DPU。要查看各个作业运行的指标，请选择作业运行并选择 **View run metrics (查看运行指标)**。

![\[显示 ETL 数据移动的作业指标。\]](http://docs.aws.amazon.com/zh_cn/glue/latest/dg/images/monitor-debug-capacity-2.png)


查看[读取](monitoring-awsglue-with-cloudwatch-metrics.md#glue.ALL.s3.filesystem.read_bytes)和[写入](monitoring-awsglue-with-cloudwatch-metrics.md#glue.ALL.s3.filesystem.write_bytes)的 Amazon S3 字节，请注意，该任务花费全部六分钟时间流式传输来自 Amazon S3 的数据并将其并行写出。已分配 DPU 上的所有核心都在读取和写入 Amazon S3。所需最大执行程序数为 107，同样与输入 Amazon S3 路径中的文件数 428 相匹配。每个执行程序可以启动四个 Spark 任务来处理四个输入文件（JSON gzip 类型）。

## 确定最佳 DPU 容量
<a name="monitor-debug-capacity-fix"></a>

根据先前作业运行的结果，您可以将已分配 DPU 总数增加到 55，并查看作业的执行情况。该任务在不到三分钟的时间内完成 – 是之前所需时间的一半。在这种情况下，作业扩展不是线性的，因为它是一个短时间运行作业。具有长期任务或大量任务（所需最大执行程序数）的作业受益于接近线性的 DPU 扩展性能加速。

![\[显示不断增加的已分配 DPU 总数的图表\]](http://docs.aws.amazon.com/zh_cn/glue/latest/dg/images/monitor-debug-capacity-3.png)


如上图所示，活动执行程序的总数达到最大分配数 – 107 个执行程序。同样，所需的最大执行程序数永远不会超过最大已分配执行程序数。所需的最大执行程序数根据主动运行和待处理任务计数计算，因此可能小于活动执行程序的数量。这是因为可能有执行程序在短时间内部分或完全空闲且尚未停用。

![\[显示活动执行程序总数达到已分配最大数的图表。\]](http://docs.aws.amazon.com/zh_cn/glue/latest/dg/images/monitor-debug-capacity-4.png)


此任务运行使用 6 倍以上的执行程序来并行地在 Amazon S3 中读取和写入。因此，此任务运行使用更多 Amazon S3 带宽进行读取和写入，并且完成得更快。

### 识别过度预配置的 DPU
<a name="monitor-debug-capacity-over"></a>

接下来，您可以确定使用 100 个 DPU（99 \$1 2 = 198 个执行程序）扩展作业是否有助于进一步扩展。如下图所示，该作业仍需要三分钟才能完成。同样，作业不会扩展超出 107 个执行程序（55 个 DPU 配置），其余 91 个执行程序被过度配置而根本未使用。这表明增加 DPU 的数量可能并不会始终提高性能，这从所需的最大执行程序数可以看出。

![\[显示作业性能并不会始终随着 DPU 数量增加而提高的图表。\]](http://docs.aws.amazon.com/zh_cn/glue/latest/dg/images/monitor-debug-capacity-5.png)


### 比较时间差异
<a name="monitor-debug-capacity-time"></a>

下表中显示的三次作业运行汇总了 10 个 DPU、55 个 DPU 和 100 个 DPU 的作业执行时间。您可以使用通过监控第一次作业运行建立的估计值来查找 DPU 容量以缩短作业执行时间。


| 作业 ID | DPU 数量 | 执行时间 | 
| --- | --- | --- | 
| jr\$1c894524c8ef5048a4d9... | 10 | 6 分钟 | 
| jr\$11a466cf2575e7ffe6856... | 55 | 3 分钟 | 
| jr\$134fa1ed4c6aa9ff0a814... | 100 | 3 分钟 | 

# AWS 中 Apache Spark 的生成式人工智能故障排除
<a name="troubleshoot-spark"></a>

 AWS 中 Apache Spark 作业的生成式人工智能故障排除是一项新功能，可帮助数据工程师和科学家轻松诊断和修复其 Spark 应用程序中的问题。该功能利用机器学习和生成式人工智能技术，分析 Spark 作业中的问题，并提供详细的根本原因分析以及解决这些问题的可行建议。Apache Spark 的生成式人工智能故障排除适用于在 AWS Glue 版本 4.0 及以下版本上运行的作业。


|  | 
| --- |
|  使用我们人工智能驱动的故障排除代理改变 Apache Spark 故障排除，该代理现在支持所有主要的部署模式，包括 AWS Glue、Amazon EMR-EC2、Amazon EMR-Serverless 和 Amazon SageMaker AI 笔记本。这款强大的代理通过将自然语言交互、实时工作负载分析和智能代码建议整合到无缝体验中，从而消除了复杂的调试过程。有关实施详细信息，请参阅[什么是适用于 Amazon EMR 的 Apache Spark 故障排除代理](https://docs.aws.amazon.com/emr/latest/ReleaseGuide/spark-troubleshoot.html)。查看[使用故障排除代理](https://docs.aws.amazon.com/emr/latest/ReleaseGuide/spark-troubleshooting-using-troubleshooting-agent.html)进行 AWS Glue 故障排除示例中的第二个演示。  | 

## Apache Spark 的生成式人工智能故障排除如何工作？
<a name="troubleshoot-spark-how-it-works"></a>

 对于失败的 Spark 作业，生成式人工智能故障排除会分析作业元数据以及与作业错误签名相关的精确指标和日志，以生成根本原因分析，并建议具体的解决方案和最佳实践来帮助解决作业失败。

## 为您的作业设置 Apache Spark 的生成式人工智能故障排除
<a name="w2aac37c11c12c33c13"></a>

### 配置 IAM 权限
<a name="troubleshoot-spark-iam-permissions"></a>

 向 AWS Glue 中的作业授予 Spark 故障排除功能所使用 API 的权限需要相应的 IAM 权限。您可以通过将以下自定义 AWS 策略附加到您的 IAM 身份（例如用户、角色或组）来获取权限。

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

****  

```
{
  "Version":"2012-10-17",		 	 	 
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "glue:StartCompletion",
        "glue:GetCompletion"
      ],
      "Resource": [
        "arn:aws:glue:*:*:completion/*",
        "arn:aws:glue:*:*:job/*"
      ]
    }
  ]
}
```

------

**注意**  
 IAM 策略中使用了以下两个 API，用于通过 AWS Glue Studio 控制台实现这种体验：`StartCompletion` 和 `GetCompletion`。

### 分配权限
<a name="troubleshoot-spark-assigning-permissions"></a>

 要提供访问权限，请为您的用户、组或角色添加权限：
+  对于 IAM Identity Center 中的用户和组：创建权限集。按照《IAM Identity Center 用户指南》中[创建权限集](https://docs.aws.amazon.com/singlesignon/latest/userguide/howtocreatepermissionset.html)的说明进行操作。
+  对于通过身份提供商在 IAM 中管理的用户：创建身份联合验证角色。按照《IAM 用户指南》中[针对第三方身份提供商创建角色（联合身份验证）](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_create_for-idp.html)的说明进行操作。
+  对于 IAM 用户：创建您的用户可以代入的角色。按照《IAM 用户指南》中[为 IAM 用户创建角色](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_create_for-user.html)的说明进行操作。

## 从失败的作业运行中运行故障排除分析
<a name="troubleshoot-spark-run-analysis"></a>

 您可以通过 AWS Glue 控制台中的多条路径访问故障排除功能。以下介绍如何开始使用：

### 选项 1：从作业列表页面
<a name="troubleshoot-spark-from-jobs-list"></a>

1.  打开 AWS Glue 控制台，网址为 [https://console.aws.amazon.com/glue/](https://console.aws.amazon.com/glue/)。

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

1.  在作业列表中找到失败的作业。

1.  在作业详细信息部分中选择**运行**选项卡。

1.  单击您要分析的失败的作业运行。

1.  选择**使用人工智能进行故障排除**以开始分析。

1.  故障排除分析完成后，您可以在屏幕底部的**故障排除分析**选项卡中查看根本原因分析和建议。

![\[GIF 显示失败运行的端到端实现以及运行人工智能功能时的故障排除。\]](http://docs.aws.amazon.com/zh_cn/glue/latest/dg/images/troubleshoot_spark_option_1_jobs_list.gif)


### 选项 2：使用作业运行监控页面
<a name="troubleshoot-spark-job-run-monitoring-page"></a>

1.  导航到**作业运行监控**页面。

1.  找到失败的作业运行。

1.  选择**操作**下拉菜单。

1.  选择**使用人工智能进行故障排除**。

![\[GIF 显示失败运行的端到端实现以及运行人工智能功能时的故障排除。\]](http://docs.aws.amazon.com/zh_cn/glue/latest/dg/images/troubleshoot_spark_option_2_job_monitoring.gif)


### 选项 3：从作业运行详细信息页面
<a name="troubleshoot-spark-job-run-details-page"></a>

1.  通过单击**运行**选项卡中失败的运行**查看详细信息**，或者从**作业运行监控**页面中选择该作业运行，导航到失败的作业运行的详细信息页面。

1.  在作业运行详细信息页面中，找到**故障排除分析**选项卡。

## 支持的故障排除类别
<a name="troubleshoot-spark-supported-troubleshooting-categories"></a>

 此服务侧重于数据工程师和开发者在其 Spark 应用程序中经常遇到的三类主要问题：
+  **资源设置和访问错误：**在 AWS Glue 中运行 Spark 应用程序时，资源设置和访问错误是最常见但最难诊断的问题之一。当 Spark 应用程序尝试与 AWS 资源交互，但遇到权限问题、缺少资源或配置问题时，通常会发生这些错误。
+  **Spark 驱动程序和执行程序内存问题：**Apache Spark 作业中与内存相关的错误可能很难诊断和解决。当数据处理要求超出驱动程序节点或执行程序节点上可用的内存资源时，通常会表现为这类错误。
+  **Spark 磁盘容量问题：**AWS Glue Spark 作业中与存储相关的错误通常会在随机操作、数据溢出或处理大规模数据转换时出现。这些错误可能特别棘手，因为它们可能要等到您的作业运行一段时间后才会表现出来，从而可能浪费宝贵的计算时间和资源。
+  **查询执行错误：**Spark SQL 和 DataFrame 操作中的查询失败往往难以排查，因为错误消息可能无法明确指向根本原因，且在小型数据集上正常运行的查询在大规模处理时可能会突然失败。当这些错误发生在复杂转换管道的深层位置时，排查难度将进一步加剧，因为实际问题可能源于早期阶段的数据质量问题，而非查询逻辑本身。

**注意**  
 在生产环境中实施任何建议的更改之前，请仔细检查建议的更改。该服务根据模式和最佳实践提供建议，但您的特定用例可能需要考虑其他注意事项。

## 支持的区域
<a name="troubleshoot-spark-supported-regions"></a>

Apache Spark 的生成式人工智能故障排除已在以下区域推出：
+ **非洲**：开普敦（af-south-1）
+ **亚太地区**：香港（ap-east-1）、东京（ap-northeast-1）、首尔（ap-northeast-2）、大阪（ap-northeast-3）、孟买（ap-south-1）、新加坡（ap-southeast-1）、悉尼（ap-southeast-2）和雅加达（ap-southeast-3）
+ **欧洲地区**：法兰克福（eu-central-1）、斯德哥尔摩（eu-north-1）、米兰（eu-south-1）、爱尔兰（eu-west-1）、伦敦（eu-west-2）和巴黎（eu-west-3）
+ **中东**：巴林（me-south-1）和阿联酋（me-central-1）
+ **北美洲**：加拿大（ca-central-1）
+ **南美洲**：圣保罗（sa-east-1）
+ **美国**：弗吉尼亚州北部（us-east-1）、俄亥俄州（us-east-2）、北加利福尼亚（us-west-1）和俄勒冈州（us-west-2）

# 通过 AWS Glue 使用实体化视图
<a name="materialized-views"></a>

AWS Glue 版本 5.1 及更高版本支持在 AWS Glue Data Catalog 中创建和管理 Apache Iceberg 实体化视图。实体化视图是一种托管表，该表以 Apache Iceberg 格式存储 SQL 查询预先计算的结果，并随着基础源表的更改而增量更新。可以使用实体化视图来简化数据转换管道并提高复杂分析工作负载的查询性能。

使用 AWS Glue 中的 Spark 创建实体化视图时，视图定义和元数据存储在 AWS Glue Data Catalog 中。预先计算的结果以 Apache Iceberg 表的形式，存储在您的账户中的 Amazon S3 表类数据存储服务存储桶或 Amazon S3 通用存储桶中。AWS Glue Data Catalog 使用托管的计算基础设施自动监控源表并刷新实体化视图。

**Topics**
+ [实体化视图如何与 AWS Glue 配合使用](#materialized-views-how-they-work)
+ [先决条件](#materialized-views-prerequisites)
+ [将 Spark 配置为使用实体化视图](#materialized-views-configuring-spark)
+ [创建实体化视图](#materialized-views-creating)
+ [查询实体化视图](#materialized-views-querying)
+ [刷新实体化视图](#materialized-views-refreshing)
+ [管理实体化视图](#materialized-views-managing)
+ [实体化视图的权限](#materialized-views-permissions)
+ [监控实体化视图操作](#materialized-views-monitoring)
+ [示例：完整工作流程](#materialized-views-complete-workflow)
+ [注意事项和限制](#materialized-views-considerations-limitations)

## 实体化视图如何与 AWS Glue 配合使用
<a name="materialized-views-how-they-work"></a>

通过 Apache Spark 在 AWS Glue 作业和 AWS Glue Studio 笔记本中对 Iceberg 的支持，实体化视图与 AWS Glue 集成。将 Spark 会话配置为使用 AWS Glue Data Catalog 时，可以使用标准 SQL 语法创建实体化视图。当实体化视图提供更好的性能时，Spark 优化器可以自动重写查询进而使用这些视图，从而无需手动修改应用程序代码。

AWS Glue Data Catalog 处理实体化视图维护的所有操作方面，包括：
+ 使用 Apache Iceberg 的元数据层检测源表中的更改
+ 使用托管的 Spark 计算计划和执行刷新操作
+ 根据数据更改确定是执行完全刷新还是增量刷新
+ 以 Apache Iceberg 格式存储预先计算的结果，便于多引擎访问

可以使用与普通表相同的 Spark SQL 接口从 AWS Glue 中查询实体化视图。也可以从其他服务访问预先计算的数据，包括 Amazon Athena 和 Amazon Redshift。

## 先决条件
<a name="materialized-views-prerequisites"></a>

要在 AWS Glue 中使用实体化视图，需要：
+  账户
+ AWS Glue 版本 5.1 或更高版本
+ 在 AWS Glue Data Catalog 中注册的 Apache Iceberg 格式的源表
+ 为源表和目标数据库配置的 AWS Lake Formation 权限
+ 通过 AWS Lake Formation 注册的 S3 表类数据存储服务存储桶或 S3 通用存储桶，用于存储实体化视图数据
+ 有权访问 AWS Glue Data Catalog 和 Amazon S3 的 IAM 角色

## 将 Spark 配置为使用实体化视图
<a name="materialized-views-configuring-spark"></a>

要在 AWS Glue 中创建和管理实体化视图，请使用所需的 Iceberg 扩展和目录设置来配置 Spark 会话。根据使用的是 AWS Glue 作业还是 AWS Glue Studio 笔记本，配置方法会有所不同。

### 配置 AWS Glue 作业
<a name="materialized-views-configuring-glue-jobs"></a>

创建或更新 AWS Glue 作业时，添加以下配置参数作为作业参数：

#### 对于 S3 表类数据存储服务存储桶
<a name="materialized-views-s3-tables-buckets"></a>

```
job = glue.create_job(
    Name='materialized-view-job',
    Role='arn:aws:iam::111122223333:role/GlueServiceRole',
    Command={
        'Name': 'glueetl',
        'ScriptLocation': 's3://amzn-s3-demo-bucket/scripts/mv-script.py',
        'PythonVersion': '3'
    },
    DefaultArguments={
        '--enable-glue-datacatalog': 'true',
        '--conf': 'spark.sql.extensions=org.apache.iceberg.spark.extensions.IcebergSparkSessionExtensions '
        '--conf spark.sql.catalog.glue_catalog=org.apache.iceberg.spark.SparkCatalog '
                  '--conf spark.sql.catalog.glue_catalog.type=glue '
                  '--conf spark.sql.catalog.glue_catalog.warehouse=s3://amzn-s3-demo-bucket/warehouse '
                  '--conf spark.sql.catalog.glue_catalog.glue.region=us-east-1 '
                  '--conf spark.sql.catalog.glue_catalog.glue.id=111122223333 '
                  '--conf spark.sql.catalog.glue_catalog.glue.account-id=111122223333 ',
                  '--conf spark.sql.catalog.glue_catalog.glue.lakeformation-enabled=true ',
                  '--conf spark.sql.catalog.s3t_catalog=org.apache.iceberg.spark.SparkCatalog '
                  '--conf spark.sql.catalog.s3t_catalog.type=glue '
                  '--conf spark.sql.catalog.s3t_catalog.glue.id=111122223333:s3tablescatalog/my-table-bucket ',
                  '--conf spark.sql.catalog.s3t_catalog.glue.account-id=111122223333 ',
                  '--conf spark.sql.catalog.s3t_catalog.glue.lakeformation-enabled=true ',
                  '--conf spark.sql.catalog.s3t_catalog.warehouse=s3://amzn-s3-demo-bucket/mv-warehouse '
                  '--conf spark.sql.catalog.s3t_catalog.glue.region=us-east-1 '
                  '--conf spark.sql.defaultCatalog=s3t_catalog '
                  '--conf spark.sql.optimizer.answerQueriesWithMVs.enabled=true '
                  '--conf spark.sql.materializedViews.metadataCache.enabled=true'
    },
    GlueVersion='5.1'
)
```

#### 对于 S3 通用存储桶
<a name="materialized-views-s3-general-purpose-buckets"></a>

```
job = glue.create_job(
    Name='materialized-view-job',
    Role='arn:aws:iam::111122223333:role/GlueServiceRole',
    Command={
        'Name': 'glueetl',
        'ScriptLocation': 's3://amzn-s3-demo-bucket/scripts/mv-script.py',
        'PythonVersion': '3'
    },
    DefaultArguments={
        '--enable-glue-datacatalog': 'true',
        '--conf': 'spark.sql.extensions=org.apache.iceberg.spark.extensions.IcebergSparkSessionExtensions '
                  '--conf spark.sql.catalog.glue_catalog=org.apache.iceberg.spark.SparkCatalog '
                  '--conf spark.sql.catalog.glue_catalog.type=glue '
                  '--conf spark.sql.catalog.glue_catalog.warehouse=s3://amzn-s3-demo-bucket/warehouse '
                  '--conf spark.sql.catalog.glue_catalog.glue.region=us-east-1 '
                  '--conf spark.sql.catalog.glue_catalog.glue.id=111122223333 ',
                  '--conf spark.sql.catalog.glue_catalog.glue.account-id=111122223333 ',
                  '--conf spark.sql.catalog.glue_catalog.glue.lakeformation-enabled=true ',
                  '--conf spark.sql.defaultCatalog=glue_catalog '
                  '--conf spark.sql.optimizer.answerQueriesWithMVs.enabled=true '
                  '--conf spark.sql.materializedViews.metadataCache.enabled=true'
    },
    GlueVersion='5.1'
)
```

### 配置 AWS Glue Studio 笔记本
<a name="materialized-views-configuring-glue-studio-notebooks"></a>

在 AWS Glue Studio 笔记本中，使用笔记本开头的 %%configure magic 命令配置 Spark 会话：

```
%%configure
{
    "conf": {
        "spark.sql.extensions": "org.apache.iceberg.spark.extensions.IcebergSparkSessionExtensions",
        "spark.sql.catalog.glue_catalog": "org.apache.iceberg.spark.SparkCatalog",
        "spark.sql.catalog.glue_catalog.type": "glue",
        "spark.sql.catalog.glue_catalog.warehouse": "s3://amzn-s3-demo-bucket/warehouse",
        "spark.sql.catalog.glue_catalog.glue.region": "us-east-1",
        "spark.sql.catalog.glue_catalog.glue.id": "111122223333",
        "spark.sql.catalog.glue_catalog.glue.account-id": "111122223333",
        "spark.sql.catalog.glue_catalog.glue.lakeformation-enabled": "true",
        "spark.sql.defaultCatalog": "glue_catalog",
        "spark.sql.optimizer.answerQueriesWithMVs.enabled": "true",
        "spark.sql.materializedViews.metadataCache.enabled": "true"
    }
}
```

### 启用增量刷新
<a name="materialized-views-enabling-incremental-refresh"></a>

要启用增量刷新优化，请在作业参数或笔记本配置中添加以下配置属性：

```
--conf spark.sql.optimizer.incrementalMVRefresh.enabled=true
--conf spark.sql.optimizer.incrementalMVRefresh.deltaThresholdCheckEnabled=false
```

### 配置参数
<a name="materialized-views-configuration-parameters"></a>

以下配置参数控制实体化视图的行为：
+ `spark.sql.extensions` – 启用支持实体化视图所需的 Iceberg Spark 会话扩展。
+ `spark.sql.optimizer.answerQueriesWithMVs.enabled` – 启用自动查询重写，进而使用实体化视图 设置为 true 可激活此优化。
+ `spark.sql.materializedViews.metadataCache.enabled` – 启用实体化视图元数据的缓存，进行查询优化。设置为 true 可提高查询重写性能。
+ `spark.sql.optimizer.incrementalMVRefresh.enabled` – 启用增量刷新优化。设置为 true 可在刷新操作期间仅处理更改的数据。
+ `spark.sql.optimizer.answerQueriesWithMVs.decimalAggregateCheckEnabled` – 控制查询重写中十进制聚合操作的验证。设置为 false 可禁用某些十进制溢出检查。

## 创建实体化视图
<a name="materialized-views-creating"></a>

可以在 AWS Glue 作业或笔记本中使用 CREATE MATERIALIZED VIEW SQL 语句创建实体化视图。视图定义将转换逻辑指定为引用一个或多个源表的 SQL 查询。

### 在 AWS Glue 作业中创建基本实体化视图
<a name="materialized-views-creating-basic-glue-jobs"></a>

以下示例演示如何在 AWS Glue 作业脚本中创建实体化视图，在视图定义中使用具有三部分命名约定的完全限定表名：

```
from awsglue.context import GlueContext
from pyspark.context import SparkContext

sc = SparkContext()
glueContext = GlueContext(sc)
spark = glueContext.spark_session

# Create materialized view
spark.sql("""
    CREATE MATERIALIZED VIEW customer_orders
    AS 
    SELECT 
        customer_name, 
        COUNT(*) as order_count, 
        SUM(amount) as total_amount 
    FROM glue_catalog.sales.orders
    GROUP BY customer_name
""")
```

### 创建具有自动刷新功能的实体化视图
<a name="materialized-views-creating-automatic-refresh"></a>

要配置自动刷新，请在创建视图时指定刷新计划，在视图定义中使用具有三部分命名约定的完全限定表名：

```
spark.sql("""
    CREATE MATERIALIZED VIEW customer_orders
    SCHEDULE REFRESH EVERY 1 HOUR
    AS 
    SELECT 
        customer_name, 
        COUNT(*) as order_count, 
        SUM(amount) as total_amount 
    FROM glue_catalog.sales.orders
    GROUP BY customer_name
""")
```

### 创建具有跨目录引用的实体化视图
<a name="materialized-views-creating-cross-catalog"></a>

当源表与实体化视图位于不同的目录中时，请在视图名称和视图定义中使用具有三部分命名约定的完全限定表名：

```
spark.sql("""
    CREATE MATERIALIZED VIEW s3t_catalog.analytics.customer_summary
    AS 
    SELECT 
        customer_name, 
        COUNT(*) as order_count, 
        SUM(amount) as total_amount 
    FROM glue_catalog.sales.orders
    GROUP BY customer_name
""")
```

### 在 AWS Glue Studio 笔记本中创建实体化视图
<a name="materialized-views-creating-glue-studio-notebooks"></a>

在 AWS Glue Studio 笔记本中，可以使用 %%sql magic 命令来创建实体化视图，在视图定义中使用具有三部分命名约定的完全限定表名：

```
%%sql
CREATE MATERIALIZED VIEW customer_orders
AS 
SELECT 
    customer_name, 
    COUNT(*) as order_count, 
    SUM(amount) as total_amount 
FROM glue_catalog.sales.orders
GROUP BY customer_name
```

## 查询实体化视图
<a name="materialized-views-querying"></a>

创建实体化视图后，可以像在 AWS Glue 作业或笔记本中使用标准 SQL SELECT 语句一样查询该视图。

### 在 AWS Glue 作业中查询
<a name="materialized-views-querying-glue-jobs"></a>

```
from awsglue.context import GlueContext
from pyspark.context import SparkContext

sc = SparkContext()
glueContext = GlueContext(sc)
spark = glueContext.spark_session

# Query materialized view
result = spark.sql("SELECT * FROM customer_orders")
result.show()
```

### 在 AWS Glue Studio 笔记本中查询
<a name="materialized-views-querying-glue-studio-notebooks"></a>

```
%%sql
SELECT * FROM customer_orders
```

### 自动查询重写
<a name="materialized-views-automatic-query-rewrite"></a>

启用自动查询重写后，Spark 优化器会分析您的查询，并在实体化视图可以提高性能时自动使用这些视图。例如，如果执行以下查询：

```
result = spark.sql("""
    SELECT 
        customer_name, 
        COUNT(*) as order_count, 
        SUM(amount) as total_amount 
    FROM orders
    GROUP BY customer_name
""")
```

只要实体化视图是最新的，Spark 优化器就会自动重写此查询，进而使用 customer\$1orders 实体化视图而不是处理基本订单表。

### 验证自动查询重写
<a name="materialized-views-verifying-automatic-query-rewrite"></a>

要验证查询是否使用自动查询重写，请使用 EXPLAIN EXTENDED 命令：

```
spark.sql("""
    EXPLAIN EXTENDED
    SELECT customer_name, COUNT(*) as order_count, SUM(amount) as total_amount 
    FROM orders
    GROUP BY customer_name
""").show(truncate=False)
```

在执行计划中，在 BatchScan 操作中查找实体化视图名称。如果计划显示 BatchScan glue\$1catalog.analytics.customer\$1orders 而不是 BatchScan glue\$1catalog.sales.orders，则查询已被自动重写，进而使用实体化视图。

请注意，创建实体化视图后，自动查询重写需要一段时间才能填充 Spark 元数据缓存。该过程通常在 30 秒内完成。

## 刷新实体化视图
<a name="materialized-views-refreshing"></a>

可以使用两种方法刷新实体化视图：完全刷新或增量刷新。完全刷新会根据所有基表数据重新计算整个实体化视图，而增量刷新仅处理自上次刷新以来发生更改的数据。

### 在 AWS Glue 作业中手动进行完全刷新
<a name="materialized-views-manual-full-refresh-glue-jobs"></a>

要对实体化视图进行完全刷新，请执行以下操作：

```
spark.sql("REFRESH MATERIALIZED VIEW customer_orders FULL")

# Verify updated results
result = spark.sql("SELECT * FROM customer_orders")
result.show()
```

### 在 AWS Glue 作业中手动进行增量刷新
<a name="materialized-views-manual-incremental-refresh-glue-jobs"></a>

要进行增量刷新，请确保在 Spark 会话配置中启用增量刷新，然后执行：

```
spark.sql("REFRESH MATERIALIZED VIEW customer_orders")

# Verify updated results
result = spark.sql("SELECT * FROM customer_orders")
result.show()
```

AWS Glue Data Catalog 会根据视图定义和更改的数据量自动确定增量刷新是否适用。如果无法进行增量刷新，则操作将回退为完全刷新。

### 在 AWS Glue Studio 笔记本中刷新
<a name="materialized-views-refreshing-glue-studio-notebooks"></a>

在笔记本中，使用 %%sql magic 命令：

```
%%sql
REFRESH MATERIALIZED VIEW customer_orders FULL
```

### 验证增量刷新执行情况
<a name="materialized-views-verifying-incremental-refresh"></a>

要确认增量刷新已成功执行，请在 AWS Glue 作业中启用调试日志记录：

```
from awsglue.context import GlueContext
from pyspark.context import SparkContext
import logging

sc = SparkContext()
glueContext = GlueContext(sc)
spark = glueContext.spark_session

# Enable debug logging
logger = logging.getLogger('org.apache.spark.sql')
logger.setLevel(logging.DEBUG)

# Execute refresh
spark.sql("REFRESH MATERIALIZED VIEW customer_orders")
```

在 AWS Glue 作业日志中搜索以下消息：

```
DEBUG RefreshMaterializedViewExec: Executed Incremental Refresh
```

## 管理实体化视图
<a name="materialized-views-managing"></a>

AWS Glue 提供了 SQL 命令，用于管理作业和笔记本中实体化视图的生命周期。

### 描述实体化视图
<a name="materialized-views-describing"></a>

要查看有关实体化视图的元数据，包括其定义、刷新状态和上次刷新时间戳，请执行以下操作：

```
spark.sql("DESCRIBE EXTENDED customer_orders").show(truncate=False)
```

### 更改实体化视图
<a name="materialized-views-altering"></a>

要修改现有实体化视图的刷新计划，请执行以下操作：

```
spark.sql("""
    ALTER MATERIALIZED VIEW customer_orders 
    ADD SCHEDULE REFRESH EVERY 2 HOURS
""")
```

要移除自动刷新，请执行以下操作：

```
spark.sql("""
    ALTER MATERIALIZED VIEW customer_orders 
    DROP SCHEDULE
""")
```

### 删除实体化视图
<a name="materialized-views-dropping"></a>

要删除实体化视图，请执行以下操作：

```
spark.sql("DROP MATERIALIZED VIEW customer_orders")
```

此命令从 AWS Glue Data Catalog 中移除实体化视图定义，并从 S3 存储桶中删除底层 Iceberg 表数据。

### 列出实体化视图
<a name="materialized-views-listing"></a>

要列出数据库中的所有实体化视图，请执行以下操作：

```
spark.sql("SHOW VIEWS FROM analytics").show()
```

## 实体化视图的权限
<a name="materialized-views-permissions"></a>

要创建和管理实体化视图，必须配置 AWS Lake Formation 权限。创建实体化视图的 IAM 角色（定义者角色）需要对源表和目标数据库的特定权限。

### 定义者角色所需的权限
<a name="materialized-views-required-permissions-definer-role"></a>

定义者角色必须具有以下 Lake Formation 权限：
+ 在源表上 – 不带行、列或单元格筛选条件的 SELECT 或 ALL 权限
+ 在目标数据库上 – CREATE\$1TABLE 权限
+ 在 AWS Glue Data Catalog 上 – GetTable 和 CreateTable API 权限

创建实体化视图时，定义者角色的 ARN 存储在视图定义中。AWS Glue Data Catalog 在执行自动刷新操作时担任此角色。如果定义者角色失去对源表的访问权限，则在恢复权限之前，刷新操作将失败。

### AWS Glue 作业的 IAM 权限
<a name="materialized-views-iam-permissions-glue-jobs"></a>

AWS Glue 作业的 IAM 角色需要以下权限：

```
{
    "Version": "2012-10-17",		 	 	 
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "glue:GetCatalog",
                "glue:GetCatalogs",
                "glue:GetTable",
                "glue:GetTables",
                "glue:CreateTable",
                "glue:UpdateTable",
                "glue:DeleteTable",
                "glue:GetDatabase",
                "glue:GetDatabases",
                "cloudwatch:PutMetricData"
            ],
            "Resource": "*"
        },
        {
            "Effect": "Allow",
            "Action": [
                "s3:GetObject",
                "s3:PutObject",
                "s3:DeleteObject"
            ],
            "Resource": [
                "arn:aws:s3:::amzn-s3-demo-bucket/*"
            ]
        },
        {
            "Effect": "Allow",
            "Action": [
                "s3:ListBucket"
            ],
            "Resource": [
                "arn:aws:s3:::amzn-s3-demo-bucket"
            ]
        },
        {
            "Effect": "Allow",
            "Action": [
                "logs:CreateLogGroup",
                "logs:CreateLogStream",
                "logs:PutLogEvents"
            ],
            "Resource": [
                "arn:aws:logs:*:*:*:/aws-glue/*"
            ]
        },
        {
            "Effect": "Allow",
            "Action": [
                "lakeformation:GetDataAccess"
            ],
            "Resource": "*"
        }
    ]
}
```

用于实体化视图自动刷新的角色必须拥有该角色的 iam:PassRole 权限。

```
{
  "Version":"2012-10-17",		 	 	 
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "iam:PassRole"
      ],
      "Resource": [
        "arn:aws:iam::111122223333:role/materialized-view-role-name"
      ]
    }
  ]
}
```

要让 Glue 自动刷新实体化视图，角色还必须具有以下信任策略，进而确保服务能够担任该角色。

```
{
  "Version":"2012-10-17",		 	 	 
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "iam:PassRole"
      ],
      "Resource": [
        "arn:aws:iam::111122223333:role/materialized-view-role-name"
      ]
    }
  ]
}
```

如果实体化视图存储在 S3 表类数据存储服务存储桶中，则还需要为角色添加以下权限。

```
{
  "Version": "2012-10-17",		 	 	 
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "s3tables:PutTableMaintenanceConfiguration"
      ],
      "Resource": "arn:aws:s3tables:*:123456789012:*"
    }
  ]
}
```

### 授予对实体化视图的访问权限
<a name="materialized-views-granting-access"></a>

要向其他用户授予查询实体化视图的访问权限，请使用 AWS Lake Formation 授予对实体化视图表的 SELECT 权限。用户无需直接访问基础源表即可查询实体化视图。

有关配置 Lake Formation 权限的详细信息，请参阅《AWS Lake Formation 开发人员指南》中的授予和撤销对 Data Catalog 资源的权限。

## 监控实体化视图操作
<a name="materialized-views-monitoring"></a>

AWS Glue Data Catalog 将实体化视图刷新操作的指标和日志发布到 Amazon CloudWatch。可以通过 CloudWatch 指标监控刷新状态、持续时间和处理的数据量。

### 查看作业日志
<a name="materialized-views-viewing-job-logs"></a>

要查看创建或刷新实体化视图的 AWS Glue 作业的日志，请执行以下操作：

1. 打开 AWS Glue 控制台。

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

1. 选择您的作业，然后选择“运行”。

1. 选择特定的运行并选择“日志”，查看 CloudWatch 日志。

### 设置警报
<a name="materialized-views-setting-up-alarms"></a>

要在刷新操作失败或超过预期持续时间时收到通知，请针对实体化视图指标创建 CloudWatch 警报。也可以将 Amazon EventBridge 规则配置为触发刷新事件的自动响应。

## 示例：完整工作流程
<a name="materialized-views-complete-workflow"></a>

以下示例演示了在 AWS Glue 中创建和使用实体化视图的完整工作流程。

### AWS Glue 作业脚本示例
<a name="materialized-views-example-glue-job-script"></a>

```
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

args = getResolvedOptions(sys.argv, ['JOB_NAME'])
sc = SparkContext()
glueContext = GlueContext(sc)
spark = glueContext.spark_session
job = Job(glueContext)
job.init(args['JOB_NAME'], args)

# Create database and base table
spark.sql("CREATE DATABASE IF NOT EXISTS sales")
spark.sql("USE sales")

spark.sql("""
    CREATE TABLE IF NOT EXISTS orders (
        id INT,
        customer_name STRING,
        amount DECIMAL(10,2),
        order_date DATE
    )
""")

# Insert sample data
spark.sql("""
    INSERT INTO orders VALUES 
        (1, 'John Doe', 150.00, DATE('2024-01-15')),
        (2, 'Jane Smith', 200.50, DATE('2024-01-16')),
        (3, 'Bob Johnson', 75.25, DATE('2024-01-17'))
""")

# Create materialized view
spark.sql("""
    CREATE MATERIALIZED VIEW customer_summary
    AS 
    SELECT 
        customer_name, 
        COUNT(*) as order_count, 
        SUM(amount) as total_amount 
    FROM glue_catalog.sales.orders
    GROUP BY customer_name
""")

# Query the materialized view
print("Initial materialized view data:")
spark.sql("SELECT * FROM customer_summary").show()

# Insert additional data
spark.sql("""
    INSERT INTO orders VALUES 
        (4, 'Jane Smith', 350.00, DATE('2024-01-18')),
        (5, 'Bob Johnson', 100.25, DATE('2024-01-19'))
""")

# Refresh the materialized view
spark.sql("REFRESH MATERIALIZED VIEW customer_summary FULL")

# Query updated results
print("Updated materialized view data:")
spark.sql("SELECT * FROM customer_summary").show()

job.commit()
```

### AWS Glue Studio 笔记本示例
<a name="materialized-views-example-glue-studio-notebook"></a>

```
%%configure
{
    "conf": {
        "spark.sql.extensions": "org.apache.iceberg.spark.extensions.IcebergSparkSessionExtensions",
        "spark.sql.catalog.glue_catalog": "org.apache.iceberg.spark.SparkCatalog",
        "spark.sql.catalog.glue_catalog.type": "glue",
        "spark.sql.catalog.glue_catalog.warehouse": "s3://amzn-s3-demo-bucket/warehouse",
        "spark.sql.catalog.glue_catalog.glue.region": "us-east-1",
        "spark.sql.catalog.glue_catalog.glue.id": "111122223333",
        "spark.sql.catalog.glue_catalog.glue.account-id": "111122223333",
        "spark.sql.catalog.glue_catalog.glue.lakeformation-enabled": "true",
        "spark.sql.defaultCatalog": "glue_catalog",
        "spark.sql.optimizer.answerQueriesWithMVs.enabled": "true",
        "spark.sql.materializedViews.metadataCache.enabled": "true"
    }
}
```

```
%%sql
CREATE DATABASE IF NOT EXISTS sales
```

```
%%sql
USE sales
```

```
%%sql
CREATE TABLE IF NOT EXISTS orders (
    id INT,
    customer_name STRING,
    amount DECIMAL(10,2),
    order_date DATE
)
```

```
%%sql
INSERT INTO orders VALUES 
    (1, 'John Doe', 150.00, DATE('2024-01-15')),
    (2, 'Jane Smith', 200.50, DATE('2024-01-16')),
    (3, 'Bob Johnson', 75.25, DATE('2024-01-17'))
```

```
%%sql
CREATE MATERIALIZED VIEW customer_summary
AS 
SELECT 
    customer_name, 
    COUNT(*) as order_count, 
    SUM(amount) as total_amount 
FROM glue_catalog.sales.orders
GROUP BY customer_name
```

```
%%sql
SELECT * FROM customer_summary
```

```
%%sql
INSERT INTO orders VALUES 
    (4, 'Jane Smith', 350.00, DATE('2024-01-18')),
    (5, 'Bob Johnson', 100.25, DATE('2024-01-19'))
```

```
%%sql
REFRESH MATERIALIZED VIEW customer_summary FULL
```

```
%%sql
SELECT * FROM customer_summary
```

## 注意事项和限制
<a name="materialized-views-considerations-limitations"></a>

在使用 AWS Glue 实体化视图时，请注意以下事项：
+ 实体化视图需要 AWS Glue 版本 5.1 或更高版本。
+ 源表必须是在 AWS Glue Data Catalog 中注册的 Apache Iceberg 表。Apache Hive、Apache Hudi 和 Linux Foundation Delta Lake 表在发布时不受支持。
+ 源表必须与实体化视图位于同一个区域和账户。
+ 所有源表都必须由 AWS Lake Formation 治理。不支持仅限 IAM 权限和混合访问权限。
+ 实体化视图不能将 AWS Glue Data Catalog 视图、多方言视图或其他实体化视图作为源表引用。
+ 视图定义者角色必须对所有未应用行、列或单元格筛选条件的源表具有完全读取权限（SELECT 或 ALL 权限）。
+ 实体化视图最终与源表保持一致。在刷新窗口期间，查询可能会返回过时数据。执行手动刷新，立即保持一致性。
+ 最小自动刷新间隔为一小时。
+ 增量刷新支持有限的 SQL 操作子集。视图定义必须是单个 SELECT-FROM-WHERE-GROUP BY-HAVING 块，并且不能包含集合操作、子查询、SELECT 或聚合函数中的 DISTINCT 关键字、窗口函数或 INNER JOIN 以外的联接。
+ 增量刷新不支持用户定义的函数或某些内置函数。仅支持 Spark SQL 内置函数的子集。
+ 查询自动重写仅考虑其定义属于受限 SQL 子集的实体化视图，类似于增量刷新限制。
+ CREATE MATERIALIZED VIEW 查询中不支持包含除字母数字字符和下划线之外的特殊字符的标识符。这适用于所有标识符类型，包括目录/命名空间/表名、列和结构字段名、CTE 和别名。
+ 以 \$1\$1ivm 前缀开头的实体化视图列保留供系统使用。Amazon 保留在未来版本中修改或移除这些列的权利。
+ 实体化视图定义中不支持 SORT BY、LIMIT、OFFSET、CLUSTER BY 和 ORDER BY 子句。
+ 不支持跨区域和跨账户源表。
+ 视图查询中引用的表必须使用三部分命名约定（例如，glue\$1catalog.my\$1db.my\$1table），因为自动刷新不使用默认的目录和数据库设置。
+ 完全刷新操作会覆盖整个表，并使以前的快照不可用。
+ 实体化视图定义中不支持诸如 as rand() 或 current\$1timestamp() 之类的非确定性函数。