在将大型数据集从 Amazon RDS 迁移到 Amazon S3 时,我的 AWS Glue 作业因节点丢失而失败

上次更新时间:2020 年 9 月 4 日

我正在使用 AWS Glue 将一个大型数据集从 Amazon Relational Database Service (Amazon RDS) 或本地 JDBC 数据库迁移到 Amazon Simple Storage Service (Amazon S3)。ETL 作业运行很长时间。然后,因节点丢失而失败。

简短描述

AWS Glue 使用单个连接读取整个数据集。如果迁移大型 JDBC 表,ETL 作业可能会运行很长时间,而 AWS Glue 方面没有任何进展迹象。由于磁盘空间问题(节点丢失),作业最终可能会失败。要解决此问题,请并行读取 JDBC 表。如果作业仍因节点丢失而失败,则使用 SQL 表达式作为下推谓词。

解决方法

使用以下一种或多种方法来解决 JDBC 数据集节点丢失错误。

并行读取 JDBC 表

如果表没有数字列(INT 或 BIGINT),请使用 hashfield 选项对数据进行分区。将 hashfield 设置为 JDBC 表中某列的名称。为了获得最佳效果,请选择值均匀分布的列。

如果表具有数字列,请在表中或在创建 DynamicFrame 时设置 hashpartitionshashexpression 选项:

  • hashpartitions:定义为读取数据 AWS Glue 创建的任务数
  • hashexpression:在任务之间均匀地划分行

以下示例演示了如何在使用 JDBC 连接创建 DynamicFrame 时设置 hashpartitionshashexpression:在 connection_option 中,替换 JDBC URL、用户名、密码、表名和列名。

connection_option= {"url": "jdbc:mysql://mysql–instance1.123456789012.us-east-1.rds.amazonaws.com:3306/database", "user": "your_user_name", "password": "your_password","dbtable": "your_table","hashexpression":"column_name","hashpartitions":"10"}

datasource0 = glueContext.create_dynamic_frame.from_options('mysql',connection_options=connection_option,transformation_ctx = "datasource0")

以下示例演示了如何在从 AWS Glue 目录创建 DynamicFrame 时设置 hashpartitionshashexpression

datasource0 = glueContext.create_dynamic_frame.from_catalog(database = "your_database", table_name = "your_table",additional_options={"hashexpression":"column_name","hashpartitions":"10"}, transformation_ctx = "datasource0")

注意:hashpartitions 设置较大的值会降低表的性能。这是因为每个任务都会读取整个表,随即向执行方返回一组行。

有关更多信息,请参阅并行读取 JDBC 表

使用 SQL 表达式作为下推谓词

注意:对于 Oracle 数据库,以下 SQL 表达式不能用作下推谓词。但是,此表达式确实可用作 AWS Glue(Amazon Aurora、MariaDB、Microsoft SQL Server、MySQL 和 PostgreSQL)原生支持的所有其他数据库的下推谓词。

如果表包含数十亿条记录和太字节级 (TiB) 数据,即使设置了 hashpartitionhashexpression 之后,作业也可能需要很长时间才能完成或因节点丢失而失败。要解决这些问题,请使用类似于以下内容的 SQL 表达式与 hashexpression 选项:

column_name > 1000 AND column_name < 2000 AND column_name

SQL 表达式充当下推谓词,可强制作业每次运行时读取一组行,而不是一次读取所有数据。以下是完整的语句:

datasource0 = glueContext.create_dynamic_frame.from_catalog(database = "sampledb", table_name = "test_table",additional_options={"hashexpression":"column_name > 1000 AND column_name < 2000 AND column_name","hashpartitions":"10"}, transformation_ctx = "datasource0")

注意:使用此配置时,请务必在初始作业运行时禁用作业书签。当您运行包含作业书签的作业时,AWS Glue 将记录列的最大值。再次运行作业时,AWS Glue 只处理值大于以前书签值的行。如果需要,可以在最后一次作业运行期间启用作业书签。