df.show renvoyant java.lang.ClassNotFoundException: org.postgresql.Driver

Nov 04 2020

Veuillez lire attentivement ce n'est pas une duplication de ceci .

J'essaie d'accéder à une base de données RDS via EMR sur AWS. J'ai fait ça sur Zeppelin:

from pyspark.sql import SparkSession

spark = SparkSession \
    .builder \
    .appName("Python Spark SQL basic example") \
    .config("spark.jars", "/home/hadoop/postgresql-42.2.18.jar") \
    .getOrCreate()

df = spark.read \
    .format("jdbc") \
    .option("url", "jdbc:postgresql://host:5432/base") \
    .option("dbtable", "tab") \
    .option("user", "xx") \
    .option("password", "xx") \
    .option("driver", "org.postgresql.Driver") \
    .load()

df.printSchema()

Quand j'ai exécuté j'ai eu cette erreur:

java.lang.ClassNotFoundException: org.postgresql.Driver 

J'ai donc trouvé cela et cela a bien fonctionné car je peux voir le schéma de ma table (j'ai ajouté la variable spark.driver.extraClassPath dans mes configurations d'interpréteur):

root
 |-- domaine: string (nullable = true)
 |-- traitement: string (nullable = true)
 |-- parquet: string (nullable = true)
 |-- status: string (nullable = true)
 |-- date: date (nullable = true) 

MAIS, quand j'essaye de faire df.show()pour voir le contenu de la table, cela renvoie la même erreur d'avant:

Py4JJavaError: An error occurred while calling o118.showString.
: org.apache.spark.SparkException: Job aborted due to stage failure: Task 0 in stage 0.0 failed 4 times, most recent failure: Lost task 0.3 in stage 0.0 (TID 3, host, executor 1): java.lang.ClassNotFoundException: org.postgresql.Driver
    at org.apache.spark.repl.ExecutorClassLoader.findClass(ExecutorClassLoader.scala:124)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:418)

Je ne comprends pas pourquoi je peux voir le schéma mais pas le contenu.

De l'aide? Je vous remercie.

Réponses

Snigdhajyoti Nov 05 2020 at 02:41

Lorsque vous soumettez, un maître d'application de travail hadoop peut être créé sur n'importe lequel de vos noeuds worker, y compris le noeud maître (en fonction de votre configuration). Si vous utilisez EMR, votre maître d'application est créé par défaut sur l'un de vos nœuds worker (nœud CORE) mais pas sur le maître.

Votre fichier existe sur /home/hadoop/postgresql-42.2.18.jarje suppose que cela signifie sur le nœud maître.
Votre programme recherchera ce fichier sur ce nœud où se trouve le maître d'application et ce n'est certainement pas sur votre nœud maître car pour cela, vous n'obtiendrez aucune erreur.


Pour résoudre ce problème:

  1. Mettez le fichier jar dans chaque nœud principal (pas une solution évolutive)
  2. Utilisez hdfs://. Le mettre en HDFS c'est une bien meilleure option. Ici, HDFS est partagé avec toutes les instances CORE & TASK.
  3. Identique à HDFS au lieu de S3 et récupérez-le via EMRFS ( s3://)

PS: je ne sais pas comment vous pouvez voir le schéma avec spark.driver.extraClassPath

Haha Nov 06 2020 at 20:53

J'ai résolu ce problème en ajoutant les paramètres suivants dans le menu de l'interpréteur Zeppelin:

spark.driver.extraClassPath=/home/hadoop/postgresql-42.2.18.jar 
spark.jars.packages=org.postgresql:postgresql:42.2.18