df.show restituisce java.lang.ClassNotFoundException: org.postgresql.Driver
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
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:
- Metti il vaso in ogni nodo principale (soluzione non scalabile)
- Usa
hdfs://. Mettendolo in HDFS è un'opzione molto migliore. Qui HDFS è condiviso con tutte le istanze CORE & TASK. - Come HDFS invece di S3 e recuperalo tramite EMRFS (
s3://)
PS: non so come puoi vedere lo schema con spark.driver.extraClassPath
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