JDBC连接无法从apache spark连接Teradata

时间:2015-06-24 15:47:50

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

我尝试了许多不同的方法,使用JDBC连接从Apache Spark连接到我们的Teradata环境。以下是我一直在使用的代码。

我确保我的JDBC驱动程序是正确的,因为我使用相同的驱动程序从其他平台连接到Teradata。

我在运行spark-shell时也添加了驱动程序Jars ./bin/spark-shell --jars /home/path/*.jar --driver-class-path /home/path/*.jar

任何帮助将不胜感激!

val jdbcDF = sqlContext.load("jdbc", Map(
  "url" -> "jdbc:teradata://<server_name>, TMODE=TERA, user=my_user, password=*****",
  "dbtable" -> "schema.table_name",
  "driver" -> "com.teradata.jdbc.TeraDriver"))

异常的堆栈跟踪:

warning: there were 1 deprecation warning(s); re-run with -deprecation for details
java.lang.ClassNotFoundException: com.teradata.jdbc.TeraDriver
        at scala.tools.nsc.interpreter.AbstractFileClassLoader.findClass(AbstractFileClassLoader.scala:83)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
        at org.apache.spark.sql.jdbc.package$DriverRegistry$.register(jdbc.scala:227)
        at org.apache.spark.sql.jdbc.DefaultSource.createRelation(JDBCRelation.scala:94)
        at org.apache.spark.sql.sources.ResolvedDataSource$.apply(ddl.scala:265)
        at org.apache.spark.sql.DataFrameReader.load(DataFrameReader.scala:114)
        at org.apache.spark.sql.SQLContext.load(SQLContext.scala:1242)
        at $iwC$$iwC$$iwC$$iwC$$iwC$$iwC$$iwC$$iwC.<init>(<console>:19)
        at $iwC$$iwC$$iwC$$iwC$$iwC$$iwC$$iwC.<init>(<console>:27)
        at $iwC$$iwC$$iwC$$iwC$$iwC$$iwC.<init>(<console>:29)
        at $iwC$$iwC$$iwC$$iwC$$iwC.<init>(<console>:31)
        at $iwC$$iwC$$iwC$$iwC.<init>(<console>:33)
        at $iwC$$iwC$$iwC.<init>(<console>:35)
        at $iwC$$iwC.<init>(<console>:37)
        at $iwC.<init>(<console>:39)
        at <init>(<console>:41)
        at .<init>(<console>:45)
        at .<clinit>(<console>)
        at .<init>(<console>:7)
        at .<clinit>(<console>)
        at $print(<console>)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:497)
        at org.apache.spark.repl.SparkIMain$ReadEvalPrint.call(SparkIMain.scala:1065)
        at org.apache.spark.repl.SparkIMain$Request.loadAndRun(SparkIMain.scala:1338)
        at org.apache.spark.repl.SparkIMain.loadAndRunReq$1(SparkIMain.scala:840)
        at org.apache.spark.repl.SparkIMain.interpret(SparkIMain.scala:871)
        at org.apache.spark.repl.SparkIMain.interpret(SparkIMain.scala:819)
        at org.apache.spark.repl.SparkILoop.reallyInterpret$1(SparkILoop.scala:857)
        at org.apache.spark.repl.SparkILoop.interpretStartingWith(SparkILoop.scala:902)
        at org.apache.spark.repl.SparkILoop.reallyInterpret$1(SparkILoop.scala:875)
        at org.apache.spark.repl.SparkILoop.interpretStartingWith(SparkILoop.scala:902)
        at org.apache.spark.repl.SparkILoop.reallyInterpret$1(SparkILoop.scala:875)
        at org.apache.spark.repl.SparkILoop.interpretStartingWith(SparkILoop.scala:902)
        at org.apache.spark.repl.SparkILoop.reallyInterpret$1(SparkILoop.scala:875)
        at org.apache.spark.repl.SparkILoop.interpretStartingWith(SparkILoop.scala:902)
        at org.apache.spark.repl.SparkILoop.command(SparkILoop.scala:814)
        at org.apache.spark.repl.SparkILoop.processLine$1(SparkILoop.scala:657)
        at org.apache.spark.repl.SparkILoop.innerLoop$1(SparkILoop.scala:665)
        at org.apache.spark.repl.SparkILoop.org$apache$spark$repl$SparkILoop$$loop(SparkILoop.scala:670)
        at org.apache.spark.repl.SparkILoop$$anonfun$org$apache$spark$repl$SparkILoop$$process$1.apply$mcZ$sp(SparkILoop.scala:997)
        at org.apache.spark.repl.SparkILoop$$anonfun$org$apache$spark$repl$SparkILoop$$process$1.apply(SparkILoop.scala:945)
        at org.apache.spark.repl.SparkILoop$$anonfun$org$apache$spark$repl$SparkILoop$$process$1.apply(SparkILoop.scala:945)
        at scala.tools.nsc.util.ScalaClassLoader$.savingContextLoader(ScalaClassLoader.scala:135)
        at org.apache.spark.repl.SparkILoop.org$apache$spark$repl$SparkILoop$$process(SparkILoop.scala:945)
        at org.apache.spark.repl.SparkILoop.process(SparkILoop.scala:1059)
        at org.apache.spark.repl.Main$.main(Main.scala:31)
        at org.apache.spark.repl.Main.main(Main.scala)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:497)
        at org.apache.spark.deploy.SparkSubmit$.org$apache$spark$deploy$SparkSubmit$$runMain(SparkSubmit.scala:664)
        at org.apache.spark.deploy.SparkSubmit$.doRunMain$1(SparkSubmit.scala:169)
        at org.apache.spark.deploy.SparkSubmit$.submit(SparkSubmit.scala:192)
        at org.apache.spark.deploy.SparkSubmit$.main(SparkSubmit.scala:111)
        at org.apache.spark.deploy.SparkSubmit.main(SparkSubmit.scala)

3 个答案:

答案 0 :(得分:2)

我终于有了这个工作。 spark docs上解释了它与--jars无法合作的原因:

  

JDBC驱动程序类必须对原始类加载器可见   在客户端会话和所有执行程序上。这是因为Java的   DriverManager类执行安全检查,导致它忽略   一个人去的时候,所有的驱动程序对原始类加载器都不可见   打开连接。

解决方案是:

  1. 将JDBC jar复制到群集中的每个spark节点
  2. 修改您的spark-defaults.conf以为您的驱动程序和执行程序添加extraClassPath选项
  3. 将这些添加到spark-defaults.conf:

    • spark.driver.extraClassPath
      • /usr/lib/tdch/1.4/lib/terajdbc4.jar:/usr/lib/tdch/1.4/lib/tdgssconfig.jar
    • spark.executor.extraClassPath
      • /usr/lib/tdch/1.4/lib/terajdbc4.jar:/usr/lib/tdch/1.4/lib/tdgssconfig.jar

    如果您使用的是Ambari,则可以在&#34;自定义spark-defaults&#34;下添加这两个属性。然后重新启动Spark。

答案 1 :(得分:0)

该错误是因为在运行时找不到包含驱动程序的jar。即使您在运行程序时拥有该jar,也需要将其分发到群集中的所有节点。你可以用:

来做到这一点
sc.addJar("yourDriver.jar")

如果您使用spark-submit,还可以使用--jars添加其他广告:

./bin/spark-submit \
  --class <main-class>
  --master <master-url> \
  --jars jar1.jar

答案 2 :(得分:0)

是的,可以使用Apache Spark连接到Teradata。 上面的问题是因为s​​park-shell无法调用使用Spark连接到Teradata所需的jar。 连接到Teradata所需的2个jar是terajdbc4.jar和tdgssconfig.jar。 通过使用以下提及的命令显式调用jar,启动您的spark-shell。

spark-shell --jars /path/terajdbc4.jar,/path/tdgssconfig.jar

import spark.implicits._;

import spark.sql;

val sqlcontext=new org.apache.spark.sql.SQLContext(sc);

val jdbcDF = sqlcontext.load("jdbc", Map("url" -> "jdbc:teradata://host/DBS_PORT=1025, TMODE=TERA, user=username, password=password","dbtable" -> "databasename.tablename","driver" -> "com.teradata.jdbc.TeraDriver"));

jdbcDF.coalesce(1).write.option("header", "true").csv("/path"); //To save the result as a csv file

exit();