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

Nov 04 2020

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

Snigdhajyoti Nov 05 2020 at 02:41

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:

  1. Coloque el tarro en cada nodo central (no es una solución escalable)
  2. Utilice hdfs://. Poniéndolo en HDFS es una opción mucho mejor. Aquí, HDFS se comparte con todas las instancias CORE & TASK.
  3. 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

Haha Nov 06 2020 at 20:53

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