Pourquoi ma tâche AWS Glue échoue-t-elle avec des nœuds perdus lorsque je migre un jeu de données volumineux depuis Amazon RDS vers Amazon S3 ?

Lecture de 4 minute(s)
0

Je migre un jeu de données volumineux depuis Amazon Relational Database Service (Amazon RDS) ou depuis une base de données JDBC sur site vers Amazon Simple Storage Service (Amazon S3) en utilisant AWS Glue. 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 la totalité de l'ensemble de données. Si vous migrez une grande table JDBC, la tâche ETL peut s'exécuter longtemps, sans signe d'avancement du côté d'AWS Glue. La tâche peut finalement échouer suite à des problèmes d'espace disque (perte de nœuds). Pour résoudre ce problème, lisez la table JDBC en parallèle. Si la tâche échoue toujours avec une perte de nœuds, utilisez une expression SQL comme prédicat pushdown.

Solution

Utilisez une ou plusieurs des méthodes suivantes pour résoudre les erreurs de nœud perdues pour les jeux de données JDBC.

Lire la table JDBC en parallèle

Si la table n'a pas de colonnes numériques (INT ou BIGINT), utilisez l'option hashfield pour partitionner les données. Affectez à hashfield le nom d'une colonne de la table JDBC. Pour obtenir des résultats optimaux, choisissez une colonne avec une distribution uniforme des valeurs.

Si la table contient des colonnes numériques, définissez les options hashpartitions et hashexpression dans la table ou pendant la création du DynamicFrame :

  • hashpartitions : définit le nombre de tâches qu'AWS Glue crée pour lire les données.
  • hashexpression : divise les lignes de manière uniforme entre les tâches.

Voici un exemple de définition de hashpartitions et hashexpression lors de la création d'un DynamicFrame en utilisant une connexion JDBC. Dans connection_option, remplacez l'URL JDBC, le nom d'utilisateur, le mot de passe, le nom de table et le nom de 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")

Voici un exemple de définition de hashpartitions et hashexpression lors de la création d'un DynamicFrame depuis le catalogue 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 : la définition de valeurs plus élevées pour hashpartitions peut réduire les performances de votre table. Cela s'explique par le fait que chaque tâche lit la totalité de la table, puis renvoie un ensemble de lignes à l'exécuteur.

Pour plus d'informations, consultez Lecture des tables JDBC en parallèle.

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. Cependant, elle fonctionne comme prédicat pushdown pour toutes les autres bases de données prises en charge en natif par AWS Glue (Amazon Aurora, MariaDB, Microsoft SQL Server, MySQL et PostgreSQL).

Si la table contient des milliards d'enregistrements et des tébioctets (Tio) de données, l'exécution de la tâche peut durer longtemps ou échouer, même après avoir défini hashpartitions et hashexpression. 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 fait office de prédicat pushdown et force la tâche à lire un ensemble de lignes chaque fois qu'elle s'exécute au lieu de lire toutes les données à la fois. L'instruction complète ressemble à ce qui 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 : veillez à désactiver 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 de nouveau la tâche, AWS Glue traite uniquement les lignes qui ont des valeurs supérieures à la valeur de signet précédente. Vous pouvez activer les signets de tâche lors de la dernière exécution de la tâche, si nécessaire.


Informations connexes

Pourquoi ma tâche AWS Glue échoue-t-elle avec l'erreur « Exit status: -100. Diagnostics: Container released on a *lost* node » (Statut de sortie : -100. Diagnostic : conteneur lancé sur un nœud *perdu*) ?

Définition de connexions dans le catalogue de données AWS Glue

AWS OFFICIEL
AWS OFFICIELA mis à jour il y a 2 ans