2016-03-23 7 views
2

Ich mache meine ersten eigenen Schritte mit Spark und Zeppelin und verstehe nicht, warum dieses Codebeispiel nicht funktioniert.Apache-Zeppelin/Spark: Warum kann ich mit diesem Codebeispiel nicht auf eine Remote-DB zugreifen

Erster Block:

%dep 
z.reset()              // clean up 
z.load("/data/extraJarFiles/postgresql-9.4.1208.jar")   // load a jdbc driver for postgresql  

zweiten Block

%spark 
// This code loads some data from a PostGreSql DB with the help of a JDBC driver. 
// The JDBC driver is stored on the Zeppelin server, the necessary Code is transfered to the Spark Workers and the workers build the connection with the DB. 
// 
// The connection between table and data source is "lazy". So the data will only be loaded in the case that an action need them. 
// With the current script means this the DB is queried twice. ==> Q: How can I keep a RDD in Mem or on disk? 

import org.apache.spark.SparkContext 
import org.apache.spark.SparkContext._ 
import org.apache.spark.SparkConf 
import org.apache.spark.rdd.JdbcRDD 
import java.sql.Connection 
import java.sql.DriverManager 
import java.sql.ResultSet 

import org.apache.spark.sql.hive._ 
import org.apache.spark.sql._ 

val url = "jdbc:postgresql://10.222.22.222:5432/myDatabase" 
val username = "postgres" 
val pw = "geheim" 

Class.forName("org.postgresql.Driver").newInstance        // activating the jdbc driver. The jar file was loaded inside of the %dep block 


case class RowClass(Id:Integer, Col1:String , Col2:String)       // create a class with possible values 

val myRDD = new JdbcRDD(sc,             // SparkContext sc 
         () => DriverManager.getConnection(url,username,pw), // scala.Function0<java.sql.Connection> getConnection 
         "select * from tab1 where \"Id\">=? and \"Id\" <=? ", // String sql Important: we need here two '?' for the lower/upper Bounds vlaues 
         0,              // long lowerBound = start value 
         10000,            // long upperBound, = end value that is still included 
         1,              // int numPartitions = the area is spitted into x sub commands. 
                       // e.g. 0,1000,2 => first cmd from 0 ... 499, second cmd from 500..1000 
         row => RowClass(row.getInt("Id"), 
             row.getString("Col1"), 
             row.getString("Col2")) 
         ) 

myRDD.toDF().registerTempTable("Tab1") 

// --- improved methode (not working at the moment)---- 
val prop = new java.util.Properties 
prop.setProperty("user",username) 
prop.setProperty("password",pw) 

val tab1b = sqlContext.read.jdbc(url,"tab1",prop)    // <-- not working 

tab1b.show 

Also, was ist das Problem.

Ich möchte eine Verbindung zu einer externen PostgreSql DB herstellen.

Block I fügt die erforderliche JAR-Datei für den DB hinzu und die ersten Zeilen des zweiten Blocks verwenden bereits das JAR und können einige Daten aus dem DB abrufen.

Aber der erste Weg ist hässlich, weil Sie die Daten selbst in eine Tabelle konvertieren müssen, also möchte ich die einfachere Methode am Ende des Skripts verwenden.

Aber ich erhalte die Fehlermeldung

java.sql.SQLException: Keine passenden Treiber für jdbc gefunden: postgresql: //10.222.22.222: 5432/mydatabase

Aber es ist die gleiche URL/der selbe Login/selbe PW aus dem obigen Code. Warum funktioniert das nicht?

Vielleicht hat jemand einen hilfreichen Hinweis für mich.

---- Aktualisierung: 24.3. 12:15 ---

Ich glaube nicht, dass das Laden der JAR nicht funktioniert. Ich fügte ein extra val db = DriverManager.getConnection(url, username, pw); zum Testen hinzu. (Die Funktion, die innerhalb der Ausnahme fehlschlägt) Und das funktioniert gut.

Ein weiteres interessantes Detail. Wenn ich den% dep-Block und die Klassenzeile entferne, erzeugt der erste Block einen sehr ähnlichen Fehler. Gleiche Fehlermeldung; gleiche Funktion + Zeilennummer, die fehlschlägt, aber der Stapel von Funktionen ist ein bisschen anders.

Ich habe den Quellcode hier: http://code.metager.de/source/xref/openjdk/jdk8/jdk/src/share/classes/java/sql/DriverManager.java

Mein Problem in Zeile 689. Also, wenn alle Parameter in Ordnung sind, vielleicht kommt es aus dem isDriverAllowed() Check?

+0

Das Problem, das Sie haben, ist, dass Zeppelin den jdbc-Treiber für Postgres nicht geladen hat. Welche Version von Zeppelin benutzt du? – user1314742

+0

Ich benutze "Zeppelin-0.5.6". Warum aber kann der erste Block auf die DB zugreifen und der zweite funktioniert nicht? Das fühlt sich an, als ob die Funktion 'z.load()' den jdbc zu einer Liste hinzufügt, die von der Funktion 'JdbcRDD()' durchsucht wird und von der 'sqlContext.read.jdbc()' -Funktion ignoriert wird. – Xaltos

+0

Können Sie Folgendes versuchen: Fügen Sie in Ihrer Interpreter-Konfiguration die folgende Eigenschaft hinzu: 'spark.driver.extraClassPath' mit dem Wert'/data/extraJarFiles/postgresql-9.4.1208.jar'. Sie können auf die Interpreterkonfiguration zugreifen, indem Sie auf das oberste Banner von Zeppelin klicken -> Interpreter – user1314742

Antwort

1

Ich habe das gleiche Problem mit Abhängigkeiten in Zeppelin hatte, und ich musste meine Gläser zu den SPARK_SUBMIT_OPTIONS in zeepelin-env.sh hinzufügen haben sie in allen Notebooks und Absätze enthalten

SO in zeppelin-env. sh Sie ändern SPARK_SUBMIT_OPTIONS sein:

export SPARK_SUBMIT_OPTIONS="--jars /data/extraJarFiles/postgresql-9.4.1208.jar

Dann haben Sie Ihre zeppelin Instanz neu zu starten.

+0

kann du stellst deine lösung dar? was meinst du mit "Zeppelin kann mit funken kommunizieren oder kann die ganze arbeit alleine machen?" – user1314742

+0

Das war nicht die richtige antwort für meinen fall, aber es hat mich dazu geführt Lösung Zeppelin kann mit Funke kommunizieren oder alle Arbeiten in einem Standalone - Modus selbst erledigen Der Parameter SPARK_SUBMIT_OPTIONS wird nur in Verbindung mit Spark verwendet Meine kleine Testumgebung läuft im Standalone - Modus, also ignorierte sie die Parameter Aber mit dem Hinweis, dass Zeppelin andere Programme aufruft, könnte ich das mit einem einfachen 'ps -efH'-Befehl verfolgen: Zeppelin führt interpreter.sh aus und ruft wieder Java auf. Also habe ich meine JAR-Datei in einen Ordner aus dem verwendeten Klassenpfad verschoben und alles funktioniert. – Xaltos

+0

Genau ... Der Interpreter-Prozess, der für einen Funkeninterpreter ein Funkenprozess ist. Es ist, als ob du Funken-Shell machst. – user1314742

0

In meinem Fall habe ich bei der Ausführung eines Spark/Scala-Codes den gleichen Fehler erhalten. Ich hatte zuvor SPARK_CLASSPATH in meiner Datei "spark-env.sh conf" festgelegt - es zeigte auf eine JAR-Datei. Ich habe die Zeile in spark-env.sh entfernt/kommentiert und Zepplin neu gestartet. Dies hat den Fehler beseitigt.

Verwandte Themen