Mam bardzo dziwny problem przy próbie załadowania JDBC DataFrame do Spark SQL.Wykrywanie java.sql.SQLException: Nie znaleziono odpowiedniego sterownika podczas ładowania DataFrame do Spark SQL
Próbowałem już kilka klastrów Spark - PRZEGLĄD, samodzielny klaster i tryb pseudo rozproszony na moim laptopie. Jest powtarzalny zarówno w Spark 1.3.0, jak i 1.3.1. Problem występuje zarówno w spark-shell
, jak i podczas wykonywania kodu z spark-submit
. Próbowałem MySQL & sterowników MS SQL JDBC bez powodzenia.
Rozważmy następujące próbki:
val driver = "com.mysql.jdbc.Driver"
val url = "jdbc:mysql://localhost:3306/test"
val t1 = {
sqlContext.load("jdbc", Map(
"url" -> url,
"driver" -> driver,
"dbtable" -> "t1",
"partitionColumn" -> "id",
"lowerBound" -> "0",
"upperBound" -> "100",
"numPartitions" -> "50"
))
}
tej pory tak dobrze, schemat zostanie rozwiązany poprawnie:
t1: org.apache.spark.sql.DataFrame = [id: int, name: string]
Ale kiedy ocenia DataFrame: występuje
t1.take(1)
następujący wyjątek:
15/04/29 01:56:44 WARN TaskSetManager: Lost task 0.0 in stage 0.0 (TID 0, 192.168.1.42): java.sql.SQLException: No suitable driver found for jdbc:mysql://<hostname>:3306/test
at java.sql.DriverManager.getConnection(DriverManager.java:689)
at java.sql.DriverManager.getConnection(DriverManager.java:270)
at org.apache.spark.sql.jdbc.JDBCRDD$$anonfun$getConnector$1.apply(JDBCRDD.scala:158)
at org.apache.spark.sql.jdbc.JDBCRDD$$anonfun$getConnector$1.apply(JDBCRDD.scala:150)
at org.apache.spark.sql.jdbc.JDBCRDD$$anon$1.<init>(JDBCRDD.scala:317)
at org.apache.spark.sql.jdbc.JDBCRDD.compute(JDBCRDD.scala:309)
at org.apache.spark.rdd.RDD.computeOrReadCheckpoint(RDD.scala:277)
at org.apache.spark.rdd.RDD.iterator(RDD.scala:244)
at org.apache.spark.rdd.MapPartitionsRDD.compute(MapPartitionsRDD.scala:35)
at org.apache.spark.rdd.RDD.computeOrReadCheckpoint(RDD.scala:277)
at org.apache.spark.rdd.RDD.iterator(RDD.scala:244)
at org.apache.spark.scheduler.ResultTask.runTask(ResultTask.scala:61)
at org.apache.spark.scheduler.Task.run(Task.scala:64)
at org.apache.spark.executor.Executor$TaskRunner.run(Executor.scala:203)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
Kiedy próbuję otworzyć JDBC połączenia na egzekutora:
import java.sql.DriverManager
sc.parallelize(0 until 2, 2).map { i =>
Class.forName(driver)
val conn = DriverManager.getConnection(url)
conn.close()
i
}.collect()
działa idealnie:
res1: Array[Int] = Array(0, 1)
Kiedy uruchomić ten sam kod lokalny Spark, to działa doskonale także:
scala> t1.take(1)
...
res0: Array[org.apache.spark.sql.Row] = Array([1,one])
Używam Sparka fabrycznie z obsługą Hadoop 2.4.
Najprostszym sposobem odtworzenia problemu jest uruchomienie trybu Spark w pseudo rozprowadzany z start-all.sh
skryptu i uruchomić następujące polecenie:
/path/to/spark-shell --master spark://<hostname>:7077 --jars /path/to/mysql-connector-java-5.1.35.jar --driver-class-path /path/to/mysql-connector-java-5.1.35.jar
czy istnieje sposób do pracy to ok? Wygląda na poważny problem, więc dziwne, że nie pomaga tutaj szukanie w Google.
Hej @Wildfire, jak poszedłeś o edycję ścieżki klasy startowy wykonawców? Próbowałem zmodyfikować ścieżkę kontenera YARN, aby dodać słoik mysql-connector-java, ale nie naprawił błędu. Dzięki! – JKnight
@JKnight Nie mogłem wymyślić, jak dodać sterownik JDBC do bootowania ścieżki klasy na YARN, więc używam tylko poprawionej kompilacji Spark. – Wildfire