df.show retornando java.lang.ClassNotFoundException: org.postgresql.Driver
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
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:
- Coloque o jar em cada nó central (não é uma solução escalonável)
- Use
hdfs://. Colocá-lo no HDFS é uma opção muito melhor. Aqui, o HDFS é compartilhado com todas as instâncias CORE & TASK. - 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
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