Spark 无法从 SBT 找到 JDBC 驱动程序
Posted
技术标签:
【中文标题】Spark 无法从 SBT 找到 JDBC 驱动程序【英文标题】:Spark Can't Find JDBC Driver from SBT 【发布时间】:2017-07-21 00:30:24 【问题描述】:我正在尝试在 Scala Spark 应用程序中使用 JDBC,并且正在使用 sbt 进行编译。但是,当我添加行 Class.forName("com.mysql.jdbc.Driver")
时,它会引发 ClassNotFoundException。
我的 sbt 文件是这样的:
name := "SparkApp"
version := "1.0"
scalaVersion := "2.11.8"
libraryDependencies += "org.apache.spark" %% "spark-core" % "2.1.0"
libraryDependencies += "org.apache.spark" %% "spark-sql" % "2.1.0"
libraryDependencies += "com.databricks" %% "spark-csv" % "1.5.0"
libraryDependencies += "org.apache.spark" %% "spark-mllib" % "2.1.0"
libraryDependencies += "mysql" % "mysql-connector-java" % "6.0.5"
据我所知,最后一行是添加 JDBC 驱动程序所需的全部内容,但它似乎不起作用。我也尝试过Class.forName("com.mysql.jdbc.Driver").newInstance()
,但结果相同,所以我认为问题在于根本没有正确添加 jdbc 类。
【问题讨论】:
【参考方案1】:您无需提供类名即可使用 JDBC 加载数据帧。在Spark SQL documentation 之后,您只需提供"jdbc"
作为数据源格式(并且确实将连接器添加为依赖项)并设置正确的选项:
val host: String = ???
val port: Int = ???
val database: String = ???
val table: String = ???
val user: String = ???
val password: String = ???
val options = Map(
"url" -> s"jdbc:mysql://$host:$port/$database?zeroDateTimeBehavior=convertToNull",
"dbtable" -> table,
"user" -> user,
"password" -> password)
val df = spark.read.format("jdbc").options(options).load()
当您将应用程序提交到 Spark 时,您必须将 MySQL 连接器包含到您的最终 jar 文件中,或者告诉spark-submit
将包作为依赖项获取:
spark-submit --packages mysql:mysql-connector-java:6.0.5 ...
此标志也适用于 spark-shell
或 pyspark
。
【讨论】:
写入数据库怎么样?我的最终目标是获取我拥有的 DataFrame 并将其写入 MySQL 中的表中。我尝试这样做,但出现“没有合适的驱动程序”错误:val prop = new java.util.Properties() prop.setProperty("user", "username") prop.setProperty("password", "password") dataFrame.write.mode("append").jdbc("jdbc:mysql://localhost:3306/database", "table", prop)
写作应该类似地工作,使用相同的选项。你如何运行你的代码?如果您提交它,请参阅我的编辑以确保依赖项可用。
添加了 packages 参数,这似乎解决了驱动程序问题。最初给出了一个已弃用的错误,但我只需要更改为com.mysql.cj.jdbc.Driver
。本来以为 sbt 依赖就足够了。谢谢!【参考方案2】:
您的 mysql 驱动程序类 com.mysql.jdbc.Driver 它在运行时不存在于您的类路径中。如果您使用 spark-submit 运行 Spark 作业,那么您至少有两个选择:
提供 --jar 选项来指定 mysql-*.jar 的路径(参见 post)(如果工作人员和驱动程序都需要该类,请仔细查看 spark.executor.extraJavaOptions 和 spark.driver.extraJavaOptions) 构建一个 uber jar(fat jar),它将在您的应用程序 jar 中包含您的 mysql-* 类(参见 post)【讨论】:
【参考方案3】:spark-submit \
--class com.mypack.MyClass \
--master yarn --deploy-mode cluster \
--conf spark.executor.extraClassPath=$POSTGRESQL_JAR_PATH:$MYSQL_JAR_PATH \
--conf spark.driver.extraClassPath=$POSTGRESQL_JAR_PATH:$MYSQL_JAR_PATH \
其中,$POSTGRESQL_JAR_PATH
和 $MYSQL_JAR_PATH
应设置为 jar 文件的 hdfs 路径。
希望这会有所帮助。
spark.executor.extraClassPath
如果您在集群模式下运行它。
spark.driver.extraClassPath
如果您在本地运行它。
我建议将这两个选项设置为更安全。
【讨论】:
【参考方案4】:您应该在提交 spark 作业时传递驱动程序 jar,如下所示:
1) spark-submit --jars mysql-connector-java-5.1.39.jar 和您传递的其余参数
2) 如果你只是想在本地尝试使用 shell spark-shell --jars mysql-connector-java-5.1.39.jar
将驱动程序更新到您已有的驱动程序并提供该驱动程序的绝对路径
【讨论】:
以上是关于Spark 无法从 SBT 找到 JDBC 驱动程序的主要内容,如果未能解决你的问题,请参考以下文章
如何在 SBT Scala 项目中使用 MySQL JDBC 驱动程序?
[XXX] 注册了JDBC驱动程 序 [oracle.jdbc.OracleDriver]
spark和aws redshift:java.sql.SQLException:没有找到适合jdbc的驱动程序:redshift://xxx.us-west-2.redshift.amazonaws