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

Nov 04 2020

Por favor, leia com atenção que não é uma duplicação deste .

Estou tentando acessar um banco de dados RDS via EMR no AWS. Eu fiz isso no 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 executei, recebi este erro:

java.lang.ClassNotFoundException: org.postgresql.Driver 

Então, achei isso e funcionou bem, pois posso ver o esquema da minha tabela (adicionei a variável spark.driver.extraClassPath nas configurações do meu interpretador):

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

MAS, quando tento fazer df.show()para ver o conteúdo da tabela retorna o mesmo erro 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)

Não entendo por que consigo ver o esquema, mas não o conteúdo.

Qualquer ajuda? Obrigado.

Respostas

Snigdhajyoti Nov 05 2020 at 02:41

Quando você envia um aplicativo de trabalho hadoop, o mestre pode ser criado em qualquer nó de trabalho, incluindo o nó mestre (dependendo da configuração). Se você estiver usando EMR, seu aplicativo mestre por padrão será criado em qualquer um de seus nós de trabalho (nó CORE), mas não no mestre.

Seu arquivo existe em /home/hadoop/postgresql-42.2.18.jarestou assumindo que significa no nó mestre.
Seu programa irá procurar por este arquivo naquele nó onde está o aplicativo mestre e definitivamente não está em seu nó mestre porque você não obteria nenhum erro.


Para resolver este problema:

  1. Coloque o jar em cada nó central (não é uma solução escalonável)
  2. Use hdfs://. Colocá-lo no HDFS é uma opção muito melhor. Aqui, o HDFS é compartilhado com todas as instâncias CORE & TASK.
  3. Igual a HDFS, em vez de S3 e buscá-lo via EMRFS ( s3://)

PS: Não sei como você consegue ver o esquema com spark.driver.extraClassPath

Haha Nov 06 2020 at 20:53

Resolvi esse problema adicionando os seguintes parâmetros ao menu do intérprete Zeppelin:

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