Passer au contenu

Pourquoi ma tâche AWS Glue échoue-t-elle et entraîne la perte de nœuds lorsque je migre un jeu de données volumineux d'Amazon RDS vers Amazon S3 ?

Lecture de 4 minute(s)
0

J'utilise AWS Glue pour migrer un jeu de données volumineux depuis Amazon Relational Database Service (Amazon RDS) ou une base de données JDBC sur site vers Amazon Simple Storage Service (Amazon S3). Ma tâche ETL s'exécute pendant une longue période, puis échoue avec des nœuds perdus.

Brève description

AWS Glue utilise une connexion unique pour lire le jeu de données dans son intégralité. Si vous migrez une table JDBC volumineuse, la tâche ETL peut s'exécuter pendant une longue période sans aucune progression du côté d'AWS Glue. La tâche peut alors d'échouer en raison de problèmes d'espace disque (nœuds perdus). Pour résoudre ce problème, lisez la table JDBC en parallèle. Si la tâche échoue toujours avec des nœuds perdus, utilisez une expression SQL comme prédicat pushdown.

Résolution

Pour résoudre les erreurs de perte de nœud pour les jeux de données JDBC, appliquez une ou plusieurs des méthodes suivantes.

Lire la table JDBC en parallèle

Si la table ne comporte pas de colonnes numériques, telles que INT ou BIGINT, utilisez l'option hashfield pour partitionner les données. Définissez hashfield sur le nom d'une colonne de la table JDBC. Pour de meilleurs résultats, choisissez une colonne dont la distribution des valeurs est uniforme.

Si la table comporte des colonnes numériques, définissez les options hashpartitions et hashexpression dans la table ou lors de la création du DynamicFrame. Pour plus d'informations, consultez la section Lecture parallèle à partir de tables JDBC.

L'exemple suivant montre comment définir des partitions de hachage and une expression de hachage lorsque vous créez un DynamicFrame avec une connexion JDBC. Dans connection_option, remplacez l'URL JDBC, le nom d'utilisateur, le mot de passe, le nom de la table et le nom de la colonne.

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")

Remarque : Remplacez l'URL JDBC, your_user_name, your_password, your_table et column_name par vos informations.

L'exemple suivant montre comment définir des partitions de hachage et une expression de hachage lorsque vous créez un DynamicFrame à partir du catalogue de données 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")

Remarque : Si vous définissez des valeurs plus élevées pour les partitions de hachage, vous pouvez réduire les performances de votre table. En effet, chaque tâche lit la table complète, puis renvoie un ensemble de lignes au programme d’exécution.

Utiliser une expression SQL comme prédicat pushdown

Remarque : L'expression SQL suivante ne fonctionne pas comme prédicat pushdown pour les bases de données Oracle. Cette expression fonctionne comme un prédicat pushdown pour toutes les autres bases de données prises en charge nativement par AWS Glue. Ces bases de données incluent Amazon Aurora, MariaDB, Microsoft SQL Server, MySQL et PostgreSQL.

Si la table contient des milliards d'enregistrements et des tébioctets (TiB) de données, la tâche peut prendre beaucoup de temps ou échouer en cas de perte de nœuds. Ce délai ou cet échec peut se produire même après avoir défini des partitions de hachage et une expression de hachage. Pour résoudre ces problèmes, utilisez une expression SQL similaire à la suivante avec l'option hashexpression :

column_name > 1000 AND column_name < 2000 AND column_name

L'expression SQL agit comme un prédicat pushdown. L'expression force la tâche à lire un ensemble de lignes par tâche exécutée, plutôt que de lire simultanément toutes les données. L’instruction complète se présente comme suit :

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")

Remarque : Désactivez les signets de tâche pour les exécutions de tâche initiales avec cette configuration. Lorsque vous exécutez une tâche avec un signet de tâche, AWS Glue enregistre la valeur maximale de la colonne. Lorsque vous exécutez à nouveau la tâche, AWS Glue traite uniquement les lignes dont les valeurs sont supérieures à la valeur de signet précédente. Activez les signets de tâche lors de la dernière exécution de tâche, selon les besoins.

Informations connexes

Pourquoi ma tâche AWS Glue échoue-t-elle avec l'erreur « Exit status: -100. Diagnostics: Container released on a *lost* node » ?

Connexion aux données

AWS OFFICIELA mis à jour il y a 5 mois