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

Nov 04 2020

Si prega di leggere attentamente questo non è un duplicato di questo .

Sto cercando di accedere a un database RDS tramite EMR su AWS. L'ho fatto su 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()

Quando ho eseguito ho ricevuto questo errore:

java.lang.ClassNotFoundException: org.postgresql.Driver 

Quindi ho trovato questo e ha funzionato bene poiché posso vedere lo schema della mia tabella (ho aggiunto la variabile spark.driver.extraClassPath nelle mie configurazioni dell'interprete):

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

MA, quando provo a fare df.show()per vedere il contenuto della tabella restituisce lo stesso errore di prima:

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)

Non capisco perché riesco a vedere lo schema ma non il contenuto.

Qualsiasi aiuto? Grazie.

Risposte

Snigdhajyoti Nov 05 2020 at 02:41

Quando invii una domanda di lavoro hadoop, il master può essere creato su qualsiasi nodo di lavoro incluso il nodo master (a seconda della tua configurazione). Se stai utilizzando EMR, il master dell'applicazione per impostazione predefinita viene creato su uno qualsiasi dei tuoi nodi di lavoro (nodo CORE) ma non sul master.

Il tuo file esiste su /home/hadoop/postgresql-42.2.18.jarSuppongo che significhi sul nodo master.
Il tuo programma cercherà questo file su quel nodo in cui si trova il master dell'applicazione e sicuramente non è sul tuo nodo master perché per questo non otterrai alcun errore.


Per risolvere questo problema:

  1. Metti il ​​vaso in ogni nodo principale (soluzione non scalabile)
  2. Usa hdfs://. Mettendolo in HDFS è un'opzione molto migliore. Qui HDFS è condiviso con tutte le istanze CORE & TASK.
  3. Come HDFS invece di S3 e recuperalo tramite EMRFS ( s3://)

PS: non so come puoi vedere lo schema con spark.driver.extraClassPath

Haha Nov 06 2020 at 20:53

Ho risolto questo problema aggiungendo i seguenti parametri nel menu dell'interprete Zeppelin:

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