Spark Imansible trovare il driver JDBC

Quindi ho usato sbt con assembly per pacchettizzare tutte le mie dipendenze in un unico jar per i miei lavori spark. Ho diversi lavori in cui stavo usando c3p0 per configurare le informazioni del pool di connessioni, trasmetterlo, e quindi utilizzare foreachPartition per poi prendere una connessione e inserire i dati nel database. Nel mio script di build sbt, includo

 "mysql" % "mysql-connector-java" % "5.1.33" 

Ciò assicura che il connettore JDBC sia impacchettato con il lavoro. Tutto funziona alla grande.

Così recentemente ho iniziato a giocare con SparkSQL e ho capito che è molto più semplice prendere semplicemente un dataframe e salvarlo su una sorgente jdbc con le nuove funzionalità in 1.3.0

Sto ottenendo la seguente eccezione:

java.sql.SQLException: nessun driver adatto trovato per jdbc: mysql: //some.domain.com/myschema? user = user & password = password su java.sql.DriverManager.getConnection (DriverManager.java:596) su java.sql. DriverManager.getConnection (DriverManager.java:233)

Quando stavo eseguendo questo localmente, l’ho risolto impostando

 SPARK_CLASSPATH=/path/where/mysql-connector-is.jar 

In definitiva quello che voglio sapere è, perché il lavoro non è in grado di trovare il driver quando dovrebbe essere impacchettato? I miei altri lavori non hanno mai avuto questo problema. Da quello che posso dire sia c3p0 che il codice dataframe utilizzano entrambi java.sql.DriverManager (che gestisce l’importazione di tutto per te da quello che posso dire) quindi dovrebbe funzionare bene ?? Se c’è qualcosa che impedisce il funzionamento del metodo assembly, cosa devo fare per farlo funzionare?

Questa persona stava avendo un problema simile: http://apache-spark-user-list.1001560.n3.nabble.com/How-to-use-DataFrame-with-MySQL-td22178.html

Hai aggiornato i driver dei connettori alla versione più recente? Inoltre hai specificato la class del driver quando hai chiamato load ()?

 Map options = new HashMap(); options.put("url", "jdbc:mysql://localhost:3306/video_rcmd?user=root&password=123456"); options.put("dbtable", "video"); options.put("driver", "com.mysql.jdbc.Driver"); //here DataFrame jdbcDF = sqlContext.load("jdbc", options); 

In spark / conf / spark-defaults.conf, puoi anche impostare spark.driver.extraClassPath e spark.executor.extraClassPath sul percorso del tuo driver MySql .jar

Sia lo spark driver che l’executor hanno bisogno del driver mysql sul percorso della class, quindi specificarlo

 spark.driver.extraClassPath = /mysql-connector-java-5.1.36.jar spark.executor.extraClassPath = /mysql-connector-java-5.1.36.jar 

Queste opzioni sono chiaramente menzionate in spark docs : --driver-class-path postgresql-9.4.1207.jar --jars postgresql-9.4.1207.jar

L’errore che stavo facendo era menzionare queste opzioni dopo il barattolo dell’applicazione.

Tuttavia, il modo corretto è specificare queste opzioni immediatamente dopo l’invio di scintille:

spark-submit --driver-class-path /somepath/project/mysql-connector-java-5.1.30-bin.jar --jars /somepath/project/mysql-connector-java-5.1.30-bin.jar --class com.package.MyClass target/scala-2.11/project_2.11-1.0.jar

spark.driver.extraClassPath non funziona in modalità client:

Nota: in modalità client, questa configurazione non deve essere impostata tramite SparkConf direttamente nell’applicazione, poiché la JVM del driver è già stata avviata in quel punto. Invece, impostalo tramite l’opzione della riga di comando –driver-class-path o nel file delle proprietà predefinito.

La variabile Env SPARK_CLASSPATH è stata deprecata in Spark 1.0+.

Dovresti prima copiare i jar del driver jdbc in ogni executor sotto lo stesso percorso del filesystem locale e quindi utilizzare le seguenti opzioni in you spark-submit:

 --driver-class-path "driver_local_file_system_jdbc_driver1.jar:driver_local_file_system_jdbc_driver2.jar" --class "spark.executor.extraClassPath=executors_local_file_system_jdbc_driver1.jar:executors_local_file_system_jdbc_driver2.jar" 

Ad esempio, in caso di TeraData è necessario sia terajdbc4.jar che tdgssconfig.jar.

In alternativa, modifica compute_classpath.sh su tutti i nodes worker, la documentazione Spark dice:

La class di driver JDBC deve essere visibile al caricatore di classi primordiali sulla sessione client e su tutti gli esecutori. Questo perché la class DriverManager di Java esegue un controllo di sicurezza che si traduce in ignorando tutti i driver non visibili al programma di caricamento class primordiale quando si apre una connessione. Un modo conveniente per farlo è modificare compute_classpath.sh su tutti i nodes worker per includere i JAR del driver.

Esiste un semplice trucco Java per risolvere il tuo problema. È necessario specificare l’istanza Class.forName() . Per esempio:

  val customers: RDD[(Int, String)] = new JdbcRDD(sc, () => { Class.forName("com.mysql.jdbc.Driver") DriverManager.getConnection(jdbcUrl) }, "SELECT id, name from customer WHERE ? < id and id <= ?" , 0, range, partitions, r => (r.getInt(1), r.getString(2))) 

Controlla i documenti

Con la scintilla 2.2.0, il problema è stato corretto per me aggiungendo informazioni aggiuntive sul percorso della class per la sessione SparkSession nello script python:

  spark = SparkSession \ .builder \ .appName("Python Spark SQL basic example") \ .config("spark.driver.extraClassPath", "/path/to/jdbc/driver/postgresql-42.1.4.jar") \ .getOrCreate() 

Vedi la documentazione ufficiale https://spark.apache.org/docs/latest/configuration.html

Nel mio caso, spark non viene avviato da cli command, ma dal framework django https://www.djangoproject.com/

Ho avuto lo stesso problema durante l’esecuzione di lavori su un cluster Mesos in modalità cluster.

Per utilizzare un driver JDBC è necessario aggiungere la dipendenza al percorso di class del sistema non al classpath del framework. Ho trovato il modo di farlo solo aggiungendo la dipendenza nel file spark-defaults.conf in ogni istanza del cluster.

Le proprietà da aggiungere sono spark.driver.extraClassPath e spark.executor.extraClassPath e il percorso deve trovarsi nel file system locale.

Aggiungo il file jar allo SPARK_CLASSPATH in spark-env.sh, funziona.

 export SPARK_CLASSPATH=$SPARK_CLASSPATH:/local/spark-1.6.3-bin-hadoop2.6/lib/mysql-connector-java-5.1.40-bin.jar