簡體   English   中英

JDBC 連接無法從 apache spark 連接 Teradata

[英]JDBC connection fails to connect Teradata from apache spark

我嘗試了許多不同的方法來使用 JDBC 連接從 Apache Spark 連接到我們的 Teradata 環境。 下面是我一直在使用的代碼。

我確保我的 JDBC 驅動程序是正確的,因為我使用相同的驅動程序從其他平台連接到 Teradata。

在運行 spark-shell ./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)

我終於得到了這個工作。 spark docs解釋了它不適用於--jars的原因:

JDBC 驅動程序類必須對客戶端會話和所有執行程序上的原始類加載器可見。 這是因為 Java 的 DriverManager 類進行了一項安全檢查,導致它在打開連接時忽略原始類加載器不可見的所有驅動程序。

解決辦法是:

  1. 將 JDBC jar 復制到集群中的每個 Spark 節點
  2. 修改spark-defaults.conf為驅動程序和執行程序添加 extraClassPath 選項

將這些添加到 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,您可以在“Custom spark-defaults”下添加這兩個屬性,然后重新啟動 Spark。

該錯誤是因為在運行時找不到包含驅動程序的 jar。 即使你在運行你的程序時有那個 jar,你也需要將它分發到集群中的所有節點。 你可以這樣做:

sc.addJar("yourDriver.jar")

如果您使用spark-submit ,您還可以使用--jars添加額外的 jars :

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

是的,可以使用 Apache Spark 連接到 Teradata。 上述問題是因為 spark-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();

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM