对 Spark 中的错误 Amazon Glue 进行故障排除 - Amazon Glue
Amazon Web Services 文档中描述的 Amazon Web Services 服务或功能可能因区域而异。要查看适用于中国区域的差异,请参阅 中国的 Amazon Web Services 服务入门 (PDF)

本文属于机器翻译版本。若本译文内容与英语原文存在差异,则一律以英文原文为准。

对 Spark 中的错误 Amazon Glue 进行故障排除

如果您在中遇到错误 Amazon Glue,请使用以下解决方案来帮助您找到问题的根源并进行修复。

注意

该 Amazon Glue GitHub 存储库包含Amazon Glue 常见问题解答中的其他疑难解答指南。

错误:资源不可用

如果 Amazon Glue 返回资源不可用消息,则可以查看错误消息或日志,以帮助您详细了解该问题。以下作业描述了故障排除的通用方法。

  • 对于您使用的任何连接和开发终端节点,请检查您的集群是否未用尽弹性网络接口。

错误:在 VPC 中找不到 subnetId 的 S3 终端节点或 NAT 网关

检查消息中的子网 ID 和 VPC ID 可帮助您诊断问题。

  • 检查您是否设置了 Amazon Glue需要的 Amazon S3 VPC 终端节点。此外,请检查您的 NAT 网关 (如果它是您的配置的一部分)。有关更多信息,请参阅 适用于 Amazon S3 的 Amazon VPC 终端节点

错误:需要安全组中的入站规则

至少有一个安全组必须打开所有入口端口。为限制流量,入站规则中的源安全组可限制为同一安全组。

错误:需要安全组中的出站规则

至少有一个安全组必须打开所有出口端口。为限制流量,出站规则中的源安全组可限制为同一安全组。

错误:Job 运行失败,因为应向传递的角色授予该 Amazon Glue 服务的代入角色权限

定义作业的用户必须具有针对适用于 Amazon Glue的 iam:PassRole 的权限。

错误: DescribeVpcEndpoints 操作未授权。无法验证 VPC ID vpc-id

  • 检查传递给的策略以 Amazon Glue 获取ec2:DescribeVpcEndpoints权限。

错误: DescribeRouteTables 操作未授权。无法验证子网 ID:VPC 中的子网 ID:vpc-id:vpc-id

  • 检查传递给的策略以 Amazon Glue 获取ec2:DescribeRouteTables权限。

错误:调用 ec2 失败:DescribeSubnets

  • 检查传递给的策略以 Amazon Glue 获取ec2:DescribeSubnets权限。

错误:调用 ec2 失败:DescribeSecurityGroups

  • 检查传递给的策略以 Amazon Glue 获取 ec2:DescribeSecurityGroups权限。

错误:找不到可用区的子网

  • 可用区可能不可用 Amazon Glue。请在不同于消息中指定的可用区的可用区中创建和使用新子网。

错误:对 JDBC 目标进行写入时发生作业运行异常

当您运行某个对 JDBC 目标进行写入的作业时,该作业在以下情况下可能遇到错误:

  • 如果您的作业对 Microsoft SQL Server 表进行写入,而该表具有定义为 Boolean 类型的列,则必须在 SQL Server 数据库中预定义该表。在 Amazon Glue 控制台上使用带有 “在数据目标中创建表” 选项的 SQL Server 目标定义作业时,不要将任何源列映射到具有数据类型的目标列Boolean。您可能在作业运行时遇到错误。

    您可以通过执行以下操作来避免错误:

    • 选择包含 Boolean 列的现有表。

    • 编辑 ApplyMapping 转换并将源中的 Boolean 列映射到目标中的数字或字符串。

    • 编辑 ApplyMapping 转换以从源中删除 Boolean 列。

  • 如果您的作业对 Oracle 表进行写入,您可能需要调整 Oracle 对象的名称长度。在某些版本的 Oracle 中,最大标识符长度限制为 30 个字节或 128 个字节。此限制影响 Oracle 目标数据存储的表名称和列名称。

    您可以通过执行以下操作来避免错误:

    • 在您的版本的限制内为 Oracle 目标表命名。

    • 默认列名称从数据中的字段名称生成。要应对列名称长度超过限制的情况,请使用 ApplyMappingRenameField 转换将列的名称更改得不超过限制。

错误:Amazon S3:此操作对该对象的存储类无效

如果 Amazon Glue 返回此错误,则您的 Amazon Glue 任务可能正在从分区跨越 Amazon S3 存储类层的表中读取数据。

  • 通过使用存储类排除项,您可以确保您的 Amazon Glue 作业可以在这些存储类层之间有分区的表上运行。如果没有排除项,则从这些层读取数据的作业将会失败,并显示以下错误:AmazonS3Exception: The operation is not valid for the object's storage class

    有关更多信息,请参阅 排除 Amazon S3 存储类

错误:Amazon S3 超时

如果 Amazon Glue 返回连接超时错误,则可能是因为它正在尝试访问其他 Amazon 区域的 Amazon S3 存储桶。

  • Amazon S3 VPC 终端节点只能将流量路由到 Amazon 区域内的存储桶。如果您需要连接到其他区域中的存储桶,一种可能的解决方法是使用 NAT 网关。有关更多信息,请参阅 NAT 网关

错误:Amazon S3 访问被拒绝

如果对 Amazon S3 存储桶或对象 Amazon Glue 返回访问被拒绝的错误,则可能是因为所提供的 IAM 角色没有权限访问您的数据存储的策略。

  • ETL 任务必须有权访问用作源或目标的 Amazon S3 数据存储。爬网程序必须有权访问其爬取的 Amazon S3 数据存储。有关更多信息,请参阅 步骤 2:为 Amazon Glue 创建 IAM 角色

错误:Amazon S3 访问密钥 ID 不存在

如果在运行作业时 Amazon Glue 返回访问密钥 ID 不存在错误,则可能是由于以下原因之一:

  • ETL 任务使用 IAM 角色来访问数据存储和确认您的任务的 IAM 角色在任务开始前未被删除。

  • IAM 角色包含以下权限:访问您的数据存储和确认包含 s3:ListBucket 的所有已附加的 Amazon S3 策略正确无误。

错误:作业在访问带有 s3a:// URI 的 Amazon S3 时运行失败

如果作业运行时返回一个类似无法分析使用处理程序类的 XML 文档的错误,可能是由于尝试列出数百个使用 s3a:// URI 的文件时失败。改用 s3:// URI 访问您的数据存储。下面的异常跟踪突出显示了要查找的错误:

1. com.amazonaws.SdkClientException: Failed to parse XML document with handler class com.amazonaws.services.s3.model.transform.XmlResponsesSaxParser$ListBucketHandler 2. at com.amazonaws.services.s3.model.transform.XmlResponsesSaxParser.parseXmlInputStream(XmlResponsesSaxParser.java:161) 3. at com.amazonaws.services.s3.model.transform.XmlResponsesSaxParser.parseListBucketObjectsResponse(XmlResponsesSaxParser.java:317) 4. at com.amazonaws.services.s3.model.transform.Unmarshallers$ListObjectsUnmarshaller.unmarshall(Unmarshallers.java:70) 5. at com.amazonaws.services.s3.model.transform.Unmarshallers$ListObjectsUnmarshaller.unmarshall(Unmarshallers.java:59) 6. at com.amazonaws.services.s3.internal.S3XmlResponseHandler.handle(S3XmlResponseHandler.java:62) 7. at com.amazonaws.services.s3.internal.S3XmlResponseHandler.handle(S3XmlResponseHandler.java:31) 8. at com.amazonaws.http.response.AwsResponseHandlerAdapter.handle(AwsResponseHandlerAdapter.java:70) 9. at com.amazonaws.http.AmazonHttpClient$RequestExecutor.handleResponse(AmazonHttpClient.java:1554) 10. at com.amazonaws.http.AmazonHttpClient$RequestExecutor.executeOneRequest(AmazonHttpClient.java:1272) 11. at com.amazonaws.http.AmazonHttpClient$RequestExecutor.executeHelper(AmazonHttpClient.java:1056) 12. at com.amazonaws.http.AmazonHttpClient$RequestExecutor.doExecute(AmazonHttpClient.java:743) 13. at com.amazonaws.http.AmazonHttpClient$RequestExecutor.executeWithTimer(AmazonHttpClient.java:717) 14. at com.amazonaws.http.AmazonHttpClient$RequestExecutor.execute(AmazonHttpClient.java:699) 15. at com.amazonaws.http.AmazonHttpClient$RequestExecutor.access$500(AmazonHttpClient.java:667) 16. at com.amazonaws.http.AmazonHttpClient$RequestExecutionBuilderImpl.execute(AmazonHttpClient.java:649) 17. at com.amazonaws.http.AmazonHttpClient.execute(AmazonHttpClient.java:513) 18. at com.amazonaws.services.s3.AmazonS3Client.invoke(AmazonS3Client.java:4325) 19. at com.amazonaws.services.s3.AmazonS3Client.invoke(AmazonS3Client.java:4272) 20. at com.amazonaws.services.s3.AmazonS3Client.invoke(AmazonS3Client.java:4266) 21. at com.amazonaws.services.s3.AmazonS3Client.listObjects(AmazonS3Client.java:834) 22. at org.apache.hadoop.fs.s3a.S3AFileSystem.getFileStatus(S3AFileSystem.java:971) 23. at org.apache.hadoop.fs.s3a.S3AFileSystem.deleteUnnecessaryFakeDirectories(S3AFileSystem.java:1155) 24. at org.apache.hadoop.fs.s3a.S3AFileSystem.finishedWrite(S3AFileSystem.java:1144) 25. at org.apache.hadoop.fs.s3a.S3AOutputStream.close(S3AOutputStream.java:142) 26. at org.apache.hadoop.fs.FSDataOutputStream$PositionCache.close(FSDataOutputStream.java:74) 27. at org.apache.hadoop.fs.FSDataOutputStream.close(FSDataOutputStream.java:108) 28. at org.apache.parquet.hadoop.ParquetFileWriter.end(ParquetFileWriter.java:467) 29. at org.apache.parquet.hadoop.InternalParquetRecordWriter.close(InternalParquetRecordWriter.java:117) 30. at org.apache.parquet.hadoop.ParquetRecordWriter.close(ParquetRecordWriter.java:112) 31. at org.apache.spark.sql.execution.datasources.parquet.ParquetOutputWriter.close(ParquetOutputWriter.scala:44) 32. at org.apache.spark.sql.execution.datasources.FileFormatWriter$SingleDirectoryWriteTask.releaseResources(FileFormatWriter.scala:252) 33. at org.apache.spark.sql.execution.datasources.FileFormatWriter$$anonfun$org$apache$spark$sql$execution$datasources$FileFormatWriter$$executeTask$3.apply(FileFormatWriter.scala:191) 34. at org.apache.spark.sql.execution.datasources.FileFormatWriter$$anonfun$org$apache$spark$sql$execution$datasources$FileFormatWriter$$executeTask$3.apply(FileFormatWriter.scala:188) 35. at org.apache.spark.util.Utils$.tryWithSafeFinallyAndFailureCallbacks(Utils.scala:1341) 36. at org.apache.spark.sql.execution.datasources.FileFormatWriter$.org$apache$spark$sql$execution$datasources$FileFormatWriter$$executeTask(FileFormatWriter.scala:193) 37. at org.apache.spark.sql.execution.datasources.FileFormatWriter$$anonfun$write$1$$anonfun$3.apply(FileFormatWriter.scala:129) 38. at org.apache.spark.sql.execution.datasources.FileFormatWriter$$anonfun$write$1$$anonfun$3.apply(FileFormatWriter.scala:128) 39. at org.apache.spark.scheduler.ResultTask.runTask(ResultTask.scala:87) 40. at org.apache.spark.scheduler.Task.run(Task.scala:99) 41. at org.apache.spark.executor.Executor$TaskRunner.run(Executor.scala:282) 42. at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) 43. at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) 44. at java.lang.Thread.run(Thread.java:748)

错误:Amazon S3 服务令牌已过期

在将数据移入和移出 Amazon Redshift 时,使用了将在 1 小时后过期的临时 Amazon S3 凭证。如果您有长时间运行的作业,它可能会失败。有关如何设置您的长时间运行的任务以将数据移入和移出 Amazon Redshift 的信息,请参阅aws-glue-programming-etl-connect-redshift-home

错误:找不到网络接口的私有 DNS

如果作业失败或开发终端节点无法预置,则可能是因为网络设置有问题。

  • 如果您使用的是 Amazon 提供的 DNS,则值 enableDnsHostnames 必须设置为 true。有关更多信息,请参阅 DNS

错误:开发终端节点预置失败

如果 Amazon Glue 未能成功配置开发端点,则可能是因为网络设置存在问题。

  • 当您定义开发终端节点时,系统将验证 VPC、子网和安全组以确认它们是否满足特定要求。

  • 如果您提供了可选的 SSH 公有密钥,请检查它是否为有效的 SSH 公有密钥。

  • 在 VPC 控制台中检查您的 VPC 是否使用了有效的 DHCP 选项集。有关更多信息,请参阅 DHCP 选项集

  • 如果集群仍处于 PROVISIONING 状态,请联系 Amazon Web Services Support。

错误:笔记本服务器 CREATE_FAILED

如果 Amazon Glue 无法为开发端点创建笔记本服务器,则可能是由于以下问题之一:

  • Amazon Glue 在设置笔记本服务器时,将 IAM 角色传递给 Amazon EC2。该 IAM 角色必须与 Amazon EC2 具有信任关系。

  • 该 IAM 角色必须具有同名的实例配置文件。当您使用 IAM 控制台为 Amazon EC2 创建角色时,将自动创建与该角色同名的实例配置文件。请在日志中检查与无效的实例配置文件名称 iamInstanceProfile.name 有关的错误。有关更多信息,请参阅使用实例配置文件

  • 检查您的角色是否有权访问您传递的用来创建笔记本服务器的策略中的 aws-glue* 存储桶。

错误:本地笔记本无法启动

如果您的本地笔记本无法启动并报告“找不到某个目录或文件夹”错误,则可能由以下问题之一导致:

  • 如果您是在 Microsoft Windows 上运行,请确保 JAVA_HOME 环境变量指向正确的 Java 目录。您可以在不更新此变量的情况下更新 Java,而如果它指向的文件夹不再存在,Jupyter Notebook 将无法启动。

错误:运行爬网程序失败

如果 Amazon Glue 未能成功运行爬网程序来对您的数据进行分类,则可能是由于以下原因之一。首先检查 Amazon Glue 控制台爬网程序列表中是否列出了错误。检查爬网程序名称旁边是否有 感叹号图标,并将鼠标指针悬停在该图标上以查看任何相关消息。

  • 在 “日志” 下/aws-glue/crawlers查看搜寻器运行的 CloudWatch 日志。

错误:分区未更新

如果您在运行 ETL 作业时没有在数据目录中更新分区,那么日志中该DataSink类中的这些 CloudWatch 日志语句可能会有所帮助:

  • Attempting to fast-forward updates to the Catalog - nameSpace:”— 显示该作业试图修改哪个数据库、表和 catalogId。如果此处没有此语句,请检查 enableUpdateCatalog 是否设置为 true 并作为 getSink() 参数正确地传递到 additional_options 中。

  • Schema change policy behavior:”— 显示您传入的架构 updateBehavior 值。

  • Schemas qualify (schema compare):”– 将为 true 或 false。

  • Schemas qualify (case-insensitive compare):”– 将为 true 或 false。

  • 如果两者均为 false 且您的updateBehavior未设置为 UPDATE_IN_DATABASE,则您的 DynamicFrame 架构必须相同或包含数据目录表架构中显示的列的子集。

有关更新分区的更多信息,请参阅 使用 Amazon Glue ETL 任务在 Data Catalog 中更新架构并添加新分区

错误:由于版本不匹配,作业书签更新失败

您可能正在尝试对 Amazon Glue 任务进行参数化,以便在 Amazon S3 中的不同数据集上应用相同的转换/逻辑。您想在提供的位置跟踪处理过的文件。当您在同一源存储桶上运行同一作业并同时写入相同/不同目标(并发 > 1)时,该作业将失败并显示此错误:

py4j.protocol.Py4JJavaError: An error occurred while callingz:com.amazonaws.services.glue.util.Job.commit.:com.amazonaws.services.gluejobexecutor.model.VersionMismatchException: Continuation update failed due to version mismatch. Expected version 2 but found version 3

解决方案:将并发设置为 1,或不同时运行该作业。

目前, Amazon Glue 书签不支持并发作业运行,提交将失败。

错误:启用作业书签后,作业正在重新处理数据

在某些情况下,您可能启用了 Amazon Glue 作业书签,但是您的 ETL 作业正在重新处理之前运行中已经处理过的数据。检查此错误的以下常见原因:

最大并发数

如果将作业的最大并发运行次数设置为大于默认值 1 的值,可能会干扰作业书签。作业书签检查对象的上次修改时间以验证哪些对象需要重新处理时可能出现这种情况。有关更多信息,请参阅在中配置 Spark 作业的作业属性 Amazon Glue中的最大并发数讨论。

缺少作业对象

确保您的作业运行脚本以下面的提交结束:

job.commit()

包含此对象时,会 Amazon Glue 记录作业运行的时间戳和路径。如果您使用相同的路径再次运行作业,则仅 Amazon Glue 处理新文件。如果您未包含此对象并且已启用作业书签,该作业将重新处理已处理的文件和新文件,并在作业的目标数据存储中创建冗余。

缺少转换上下文参数

转换上下文是 GlueContext 类中的一个可选参数,但如果不包含该参数,作业书签将不起作用。要解决此错误,请在创建时添加转换上下文参数 DynamicFrame,如下所示:

sample_dynF=create_dynamic_frame_from_catalog(database, table_name,transformation_ctx="sample_dynF")
输入源

如果将关系数据库(JDBC 连接)用作输入源,则仅当表的主键按顺序排列时,作业书签才起作用。作业书签适用于新行,但不适用于更新的行。这是因为作业书签查找已存在的主键。如果您的输入源为 Amazon Simple Storage Service(Amazon S3),则这不适用。

上次修改时间

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

错误:中 VPC 之间的故障转移行为 Amazon Glue

在 Amazon Glue 4.0 及之前版本中,以下过程用于任务的故障转移。

摘要:在提交作业运行时选择 Amazon Glue 连接。如果作业运行遇到一些问题(缺少 IP 地址、与源的连接、路由问题),则作业运行将失败。如果配置了重试,则 Amazon Glue 将使用相同的连接重试。

  1. 提交作业运行时,根据任务配置中列出的顺序 Amazon Glue 选择连接。它运行验证,如果验证成功, Amazon Glue 将使用该连接。 Amazon Glue 如果任何验证失败,则尝试下一个连接。

  2. Amazon Glue 使用以下内容验证连接:

    • 检查 Amazon VPC ID 和子网是否有效。

    • 检查 NAT 网关或 Amazon VPC 端点是否存在。

    • 检查子网分配的 IP 地址是否超过 0 个。

    • 检查可用区是否运行正常。

    Amazon Glue 提交作业运行时无法验证连接。

  3. 对于使用 Amazon VPC 的作业,所有驱动程序和执行程序都将在同一个可用区中创建,并在提交作业运行时选择连接。

  4. 如果配置了重试,则 Amazon Glue 将使用相同的连接重试。这是因为我们不能保证此连接的问题是长期存在的。如果某个可用区出现故障,则该可用区中运行的现有作业(取决于作业运行的阶段)可能会失败。重试应该会检测到可用区故障,然后为新的运行选择另一个可用区。