Spark无法找到JDBC驱动程序

时间:2015-04-10 03:25:11

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

所以我一直在使用sbt with assembly将我的所有依赖项打包到一个jar中,用于我的spark工作。我有几个工作,我使用c3p0设置连接池信息,广播出来,然后在RDD上使用foreachPartition然后获取连接,并将数据插入到数据库。在我的sbt构建脚本中,我包括

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

这确保JDBC连接器与作业打包在一起。一切都很好。

所以最近我开始使用SparkSQL,并意识到使用1.3.0

中的新功能,简单地使用数据帧并将其保存到jdbc源更容易

我收到以下异常:

  

java.sql.SQLException:找不到合适的驱动程序   jdbc:mysql://some.domain.com/myschema?user = user& password = password at   java.sql.DriverManager.getConnection(DriverManager.java:596)at   java.sql.DriverManager.getConnection(DriverManager.java:233)

当我在本地运行时,我通过设置

来解决这个问题
SPARK_CLASSPATH=/path/where/mysql-connector-is.jar

最终我想知道的是,为什么这个工作在应该用它打包时不能找到驱动程序?我的其他工作从未遇到过这个问题。从我可以告诉c3p0和数据帧代码两者都使用java.sql.DriverManager(它从我可以告诉你处理导入所有东西)所以它应该工作得很好?如果有什么东西阻止汇编方法工作,我需要做些什么才能使它工作?

10 个答案:

答案 0 :(得分:29)

此人遇到类似问题:http://apache-spark-user-list.1001560.n3.nabble.com/How-to-use-DataFrame-with-MySQL-td22178.html

您是否已将连接器驱动程序更新为最新版本?你也在调用load()时指定了驱动程序类吗?

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

在spark / conf / spark-defaults.conf中,您还可以将spark.driver.extraClassPath和spark.executor.extraClassPath设置为MySql驱动程序的路径.jar

答案 1 :(得分:18)

spark驱动程序和执行程序都需要类路径上的mysql驱动程序,所以指定

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

答案 2 :(得分:12)

spark docs--driver-class-path postgresql-9.4.1207.jar --jars postgresql-9.4.1207.jar

中明确提到了这些选项

我正在做的错误是在我的应用程序的jar之后提到这些选项。

但正确的方法是在spark-submit后立即指定这些选项:

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

答案 3 :(得分:6)

spark.driver.extraClassPath在客户端模式下不起作用:

  

注意:在客户端模式下,不能直接在应用程序中通过SparkConf设置此配置,因为驱动程序JVM已在此时启动。相反,请通过--driver-class-path命令行选项或默认属性文件中设置它。

已在Spark 1.0 +中弃用了变量SPARK_CLASSPATH。

首先应将jdbc驱动程序jar复制到同一本地文件系统路径下的每个执行程序中,然后在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"

例如,对于TeraData,您需要terajdbc4.jar和tdgssconfig.jar。

或者修改所有工作节点上的compute_classpath.sh,Spark文档说:

  

JDBC驱动程序类必须对客户端会话和所有执行程序上的原始类加载器可见。这是因为Java的DriverManager类进行了安全检查,导致它忽略了当打开连接时原始类加载器不可见的所有驱动程序。一种方便的方法是修改所有工作节点上的compute_classpath.sh以包含驱动程序JAR。

答案 4 :(得分:5)

使用spark 2.2.0,通过在python脚本中为SparkSession会话添加额外的类路径信息来纠正问题:

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

请参阅官方文档https://spark.apache.org/docs/latest/configuration.html

就我而言,spark不是从cli命令启动的,而是从django框架https://www.djangoproject.com/启动的

答案 5 :(得分:3)

存在一个简单的Java技巧来解决您的问题。您应该指定Class.forName()实例。例如:

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

检查docs

答案 6 :(得分:1)

我在群集模式下通过Mesos群集运行作业时遇到了同样的问题。

要使用JDBC驱动程序,必须将依赖项添加到系统类路径而不是框架类路径。我只是通过在集群的每个实例中的文件spark-defaults.conf中添加依赖项来找到实现它的方法。

要添加的属性为spark.driver.extraClassPathspark.executor.extraClassPath,路径必须位于本地文件系统中。

答案 7 :(得分:1)

我将jar文件添加到spark-env.sh中的SPARK_CLASSPATH,它可以正常工作。

def get_files(page):
    a = urllib.urlopen(page)
    b = a.read()
    c = re.findall("([a-zA-Z0-9]+\.{1}(jpg|bmp|docx|gif))",b)
    return c 
def main():
    print get_files("http://www.soc.napier.ac.uk/~40001507/CSN08115/cw_webpage/index.html")

if __name__ == "__main__":
    main()

答案 8 :(得分:1)

当我尝试从Windows计算机运行spark-shell命令时,我遇到了同样的问题。您为驱动程序位置以及将要使用的jar传递的路径应该在双引号中,否则会被误解并且您将无法获得所需的确切输出。

您还必须通过以下链接安装用于SQL Server的JDBC驱动程序:JDBC Driver

我已使用以下命令在Windows计算机上正常工作:

spark-shell --driver-class-path“ C:\ Program Files \ SQL Server的Microsoft JDBC Driver 6.0 \ sqljdbc_6.0 \ enu \ jre8 \ sqljdbc42.jar” --jars“ C:\程序文件\用于SQL Server的Microsoft JDBC驱动程序6.0 \ sqljdbc_6.0 \ enu \ jre8 \ sqljdbc42.jar“

答案 9 :(得分:0)

一种简单的简便方法是将“ mysql-connector-java-5.1-47.jar ”复制到“ spark-2.4.3 \ jars \”目录中