df.show devolviendo java.lang.ClassNotFoundException: org.postgresql.Driver
Por favor lea atentamente que esto no es una duplicación de esto .
Estoy intentando acceder a una base de datos RDS a través de EMR en AWS. Hice esto en 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()
Cuando ejecuté recibí este error:
java.lang.ClassNotFoundException: org.postgresql.Driver
Entonces encontré esto y funcionó bien, ya que puedo ver el esquema de mi tabla (agregué la variable spark.driver.extraClassPath en las configuraciones de mi intérprete):
root
|-- domaine: string (nullable = true)
|-- traitement: string (nullable = true)
|-- parquet: string (nullable = true)
|-- status: string (nullable = true)
|-- date: date (nullable = true)
PERO, cuando trato de hacer df.show()para ver el contenido de la tabla, devuelve el mismo error de antes:
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)
No entiendo por qué puedo ver el esquema pero no el contenido.
¿Alguna ayuda? Gracias.
Respuestas
Cuando envía una solicitud de trabajo de hadoop, el maestro puede crearse en cualquiera de sus nodos de trabajo, incluido el nodo maestro (según su configuración). Si está utilizando EMR, su aplicación maestra por defecto se crea en cualquiera de sus nodos de trabajo (nodo CORE) pero no en la maestra.
Su archivo existe en /home/hadoop/postgresql-42.2.18.jarSupongo que eso significa en el nodo maestro.
Su programa buscará este archivo en ese nodo donde está el maestro de la aplicación y definitivamente no está en su nodo maestro porque para eso no obtendría ningún error.
Para solucionar este problema:
- Coloque el tarro en cada nodo central (no es una solución escalable)
- Utilice
hdfs://. Poniéndolo en HDFS es una opción mucho mejor. Aquí, HDFS se comparte con todas las instancias CORE & TASK. - Igual que HDFS en lugar de S3 y obtenerlo a través de EMRFS (
s3://)
PD: no sé cómo puedes ver el esquema con spark.driver.extraClassPath
Resolví este problema agregando los siguientes parámetros en el menú del intérprete de Zeppelin:
spark.driver.extraClassPath=/home/hadoop/postgresql-42.2.18.jar
spark.jars.packages=org.postgresql:postgresql:42.2.18