【问题标题】:java.sql.SQLException: No suitable driver found when loading DataFrame into Spark SQLjava.sql.SQLException:将 DataFrame 加载到 Spark SQL 时找不到合适的驱动程序
【发布时间】:2015-07-08 00:46:19
【问题描述】:

我在尝试将 JDBC DataFrame 加载到 Spark SQL 时遇到了非常奇怪的问题。

我在笔记本电脑上尝试了几个 Spark 集群 - YARN、独立集群和伪分布式模式。它可以在 Spark 1.3.0 和 1.3.1 上重现。在spark-shell 和使用spark-submit 执行代码时都会出现此问题。我尝试了 MySQL 和 MS SQL JDBC 驱动程序,但没有成功。

考虑以下示例:

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"
  ))
}

到目前为止一切顺利,架构已正确解析:

t1: org.apache.spark.sql.DataFrame = [id: int, name: string]

但是当我评估 DataFrame 时:

t1.take(1)

发生以下异常:

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)

当我尝试在执行器上打开 JDBC 连接时:

import java.sql.DriverManager

sc.parallelize(0 until 2, 2).map { i =>
  Class.forName(driver)
  val conn = DriverManager.getConnection(url)
  conn.close()
  i
}.collect()

效果很好:

res1: Array[Int] = Array(0, 1)

当我在本地 Spark 上运行相同的代码时,它也能完美运行:

scala> t1.take(1)
...
res0: Array[org.apache.spark.sql.Row] = Array([1,one])

我正在使用预构建的 Spark,支持 Hadoop 2.4。

重现该问题的最简单方法是使用 start-all.sh 脚本以伪分布式模式启动 Spark 并运行以下命令:

/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

有没有办法解决这个问题?这看起来是一个严重的问题,所以奇怪的是谷歌搜索在这里没有帮助。

【问题讨论】:

    标签: scala jdbc apache-spark apache-spark-sql


    【解决方案1】:

    显然最近有人报告了这个问题:

    https://issues.apache.org/jira/browse/SPARK-6913

    问题出在 java.sql.DriverManager 中,除了 bootstrap ClassLoader 之外,没有看到 ClassLoader 加载的驱动程序。

    作为一种临时解决方法,可以将所需的驱动程序添加到执行程序的引导类路径中。

    更新:此拉取请求解决了问题:https://github.com/apache/spark/pull/5782

    更新 2:修复合并到 Spark 1.4

    【讨论】:

    • 嘿@Wildfire,你是如何编辑执行器的引导类路径的?我尝试修改 YARN 容器类路径以添加 mysql-connector-java jar,但它没有修复错误。谢谢!
    • @JKnight 我不知道如何在 YARN 上添加 JDBC 驱动程序来启动类路径,所以我只是使用修补过的 Spark 构建。
    【解决方案2】:

    用于向 MySQL 写入数据

    在 spark 1.4.0 中,您必须在写入 MySQL 之前加载它,因为它在加载函数而不是写入函数时加载驱动程序。 我们必须将 jar 放在每个工作节点上,并在每个节点的 spark-defaults.conf 文件中设置路径。 此问题已在 spark 1.5.0 中修复

    https://issues.apache.org/jira/browse/SPARK-10036

    【讨论】:

      【解决方案3】:

      我们被困在 Spark 1.3 (Cloudera 5.4) 上,所以我发现这个问题和 Wildfire 的回答很有帮助,因为它让我不再用头撞墙。

      我想分享一下我们是如何将驱动程序放入引导类路径的:我们只是将它复制到 /opt/cloudera/parcels/CDH-5.4.0-1.cdh5.4.0.p0.27/lib/hive/lib在所有节点上。

      【讨论】:

      • 您好,您在将驱动程序添加到该文件夹​​后是否重新启动了 Cloudera?谢谢
      • @SantiArias 是的,我相信我们确实重启了集群。
      【解决方案4】:

      我在 SQL Server 上使用 spark-1.6.1,仍然遇到同样的问题。我必须将库(sqljdbc-4.0.jar)添加到实例中的 lib 和 conf/spark-dfault.conf 文件中的行下方。

      spark.driver.extraClassPath lib/sqljdbc-4.0.jar

      【讨论】:

        猜你喜欢
        • 2013-07-04
        • 2016-11-28
        • 2011-08-02
        • 2012-08-28
        • 2015-07-05
        • 2010-11-25
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多