Estoy usando AWS Glue para migrar un conjunto de datos grande de Amazon Relational Database Service (Amazon RDS) o una base de datos de JDBC local a Amazon Simple Storage Service (Amazon S3). La ejecución de mi trabajo de ETL dura mucho tiempo y al final se produce un error con pérdida de nodos.
Breve descripción
AWS Glue solo utiliza una conexión para leer todo el conjunto de datos. Si migras una tabla grande de JDBC, es posible que la ejecución del trabajo de ETL se prolongue durante mucho tiempo sin progreso en AWS Glue. En tal caso, se podría producir un error en el trabajo por problemas con el espacio en disco (pérdida de nodos). Para solucionar este problema, lee la tabla de JDBC en paralelo. Si el error de pérdida de nodos persiste en el trabajo, utiliza una expresión de SQL como predicado de apilado.
Resolución
Para solucionar los errores de pérdida de nodos en conjuntos de datos de JDBC, utiliza uno o varios de los siguientes métodos.
Lectura en paralelo de la tabla de JDBC
Si la tabla no tiene columnas numéricas, como INT o BIGINT, utiliza la opción hashfield para fragmentar los datos. Establece hashfield como nombre de una columna en la tabla de JDBC. Para obtener mejores resultados, elige una columna que tenga una distribución uniforme de los valores.
Si la tabla tiene columnas numéricas, define las opciones hashpartitions y hashexpression en la tabla o mientras creas el DynamicFrame. Para obtener más información, consulta Lectura desde tablas de JDBC en paralelo.
A continuación se muestra un ejemplo de cómo definir hashpartitions y hashexpression al crear un DynamicFrame con una conexión de JDBC. En connection_option, sustituye la URL de JDBC, el nombre de usuario, la contraseña, el nombre de la tabla y el nombre de la columna.
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")
Nota: Sustituye la URL de JDBC, your_user_name, your_password, your_table y column_name por tu información.
El siguiente es un ejemplo de cómo configurar hashpartitions y hashexpression al crear un DynamicFrame a partir del catálogo de datos de AWS Glue:
datasource0 = glueContext.create_dynamic_frame.from_catalog(database = "your_database", table_name = "your_table",additional_options={"hashexpression":"column_name","hashpartitions":"10"}, transformation_ctx = "datasource0")
Nota: Si estableces valores más altos para hashpartitions, puedes reducir el rendimiento de la tabla. Esto se debe a que cada tarea lee la tabla entera y, a continuación, devuelve un conjunto de filas al ejecutor.
Utilización de una expresión de SQL como predicado de apilado
Nota: La siguiente expresión de SQL no funciona como predicado de apilado en bases de datos de Oracle. Esta expresión funciona como un predicado desplegable para todas las demás bases de datos que AWS Glue admite de forma nativa. Estas bases de datos incluyen Amazon Aurora, MariaDB, Microsoft SQL Server, MySQL y PostgreSQL.
Si la tabla contiene miles de millones de registros y tebibytes (TiB) de datos, es posible que el trabajo tarde mucho en completarse o que se pierdan nodos. Este retraso o error puede producirse incluso después de configurar hashpartitions y hashexpression. Para solucionar estos problemas, utiliza una expresión de SQL parecida a esta con la opción hashexpression:
column_name > 1000 AND column_name < 2000 AND column_name
La expresión de SQL actúa como predicado de apilado. La expresión obliga al trabajo a leer un conjunto de filas por ejecución de trabajo, en lugar de leer todos los datos a la vez. La instrucción al completo se parece a esta:
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")
Nota: Con esta configuración, desactiva los marcadores de trabajo en el caso de las ejecuciones iniciales de trabajos. Si ejecutas un trabajo con un marcador de trabajo, AWS Glue registrará el valor máximo de la columna. Al volver a ejecutar el trabajo, AWS Glue solo procesará las filas que tengan valores superiores al valor del marcador anterior. Activa los marcadores de trabajo durante la última ejecución del trabajo si es necesario.
Información relacionada
¿Por qué se produce el error «Exit status: -100. Diagnostics: Container released on a *lost* node» en mi trabajo de AWS Glue?
Conexión a los datos