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

Nov 04 2020

Przeczytaj uważnie, że nie jest to powielenie tego .

Próbuję uzyskać dostęp do bazy danych RDS przez EMR na AWS. Zrobiłem to na Zeppelinie:

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()

Kiedy wykonałem, otrzymałem ten błąd:

java.lang.ClassNotFoundException: org.postgresql.Driver 

Znalazłem to i działało dobrze, ponieważ widzę schemat mojej tabeli (dodałem zmienną spark.driver.extraClassPath w moich konfiguracjach interpretera):

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

ALE, gdy próbuję df.show()zobaczyć zawartość tabeli, zwraca ten sam błąd co wcześniej:

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)

Nie rozumiem, dlaczego mogę zobaczyć schemat, ale nie mogę zobaczyć treści.

Jakaś pomoc? Dziękuję Ci.

Odpowiedzi

Snigdhajyoti Nov 05 2020 at 02:41

Po przesłaniu aplikacji o pracę hadoop może zostać utworzony w dowolnym węźle roboczym, w tym węźle głównym (w zależności od konfiguracji). Jeśli używasz EMR, Twój wzorzec aplikacji jest domyślnie tworzony w dowolnym węźle roboczym (węzeł CORE), ale nie w głównym.

Twój plik istnieje /home/hadoop/postgresql-42.2.18.jar, zakładam, że oznacza to w węźle głównym.
Twój program będzie szukał tego pliku w tym węźle, w którym znajduje się główny element aplikacji, i na pewno nie w węźle głównym, ponieważ w tym celu nie pojawi się żaden błąd.


Aby rozwiązać ten problem:

  1. Umieść słoik w każdym głównym węźle (rozwiązanie nie jest skalowalne)
  2. Użyj hdfs://. Umieszczenie go w HDFS to znacznie lepsza opcja. Tutaj HDFS jest współdzielony ze wszystkimi instancjami CORE & TASK.
  3. To samo co HDFS zamiast S3 i pobierz przez EMRFS ( s3://)

PS: Nie wiem, w jaki sposób możesz zobaczyć schemat spark.driver.extraClassPath

Haha Nov 06 2020 at 20:53

Rozwiązałem ten problem dodając następujące parametry w menu interpretera Zeppelina:

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