【问题标题】:Apache-Zeppelin / Spark : Why can't I access a remote DB with this code sampleApache-Zeppelin / Spark:为什么我不能使用此代码示例访问远程数据库
【发布时间】:2016-07-10 15:39:30
【问题描述】:

我正在使用 Spark 和 Zeppelin 进行自己的第一步,但不明白为什么此代码示例不起作用。

第一块:

%dep
z.reset()                                                     // clean up 
z.load("/data/extraJarFiles/postgresql-9.4.1208.jar")         // load a jdbc driver for postgresql    

第二块

%spark
// This code loads some data from a PostGreSql DB with the help of a JDBC driver.
// The JDBC driver is stored on the Zeppelin server, the necessary Code is transfered to the Spark Workers and the workers build the connection with the DB.
// 
// The connection between table and data source is "lazy".  So the data will only be loaded in the case that an action need them.
// With the current script means this the DB is queried twice.   ==> Q:  How can I keep a RDD in Mem or on disk?

import org.apache.spark.SparkContext
import org.apache.spark.SparkContext._
import org.apache.spark.SparkConf
import org.apache.spark.rdd.JdbcRDD
import java.sql.Connection
import java.sql.DriverManager
import java.sql.ResultSet

import org.apache.spark.sql.hive._ 
import org.apache.spark.sql._

val url = "jdbc:postgresql://10.222.22.222:5432/myDatabase"
val username = "postgres"
val pw = "geheim"

Class.forName("org.postgresql.Driver").newInstance                             // activating the jdbc driver. The jar file was loaded inside of the %dep block


case class RowClass(Id:Integer, Col1:String , Col2:String)                         // create a class with possible values

val myRDD = new JdbcRDD(sc,                                                    // SparkContext sc
                        () => DriverManager.getConnection(url,username,pw),    // scala.Function0<java.sql.Connection> getConnection
                        "select * from tab1 where \"Id\">=? and \"Id\" <=? ",  // String sql    Important: we need here two '?' for the lower/upper Bounds vlaues
                        0,                                                     // long lowerBound   = start value
                        10000,                                                // long upperBound,  = end value that is still included
                        1,                                                     // int numPartitions  = the area is spitted into x sub commands.   
                                                                               //  e.g. 0,1000,2  => first cmd from 0 ... 499, second cmd from 500..1000
                        row => RowClass(row.getInt("Id"),
                                        row.getString("Col1"),
                                        row.getString("Col2"))
                       )

myRDD.toDF().registerTempTable("Tab1")

// --- improved methode (not working at the moment)----
val prop = new java.util.Properties
prop.setProperty("user",username)
prop.setProperty("password",pw)

val tab1b = sqlContext.read.jdbc(url,"tab1",prop)             // <-- not working

tab1b.show

那么问题出在哪里。

我想连接到外部 PostgreSql 数据库。

块 I 正在为 DB 添加必要的 JAR 文件,第二块的第一行已经在使用 JAR,它能够从 DB 中获取一些数据。

但是第一种方法很丑,因为你必须自己将数据转换成表格,所以我想在脚本末尾使用更简单的方法。

但我收到错误消息

java.sql.SQLException:找不到合适的驱动程序 jdbc:postgresql://10.222.22.222:5432/myDatabase

但与上述代码相同的 URL / 相同的登录名 / 相同的 PW。 为什么这不起作用?

也许有人对我有帮助。

---- 更新:24.3。 12:15 ---

我不认为 JAR 的加载不起作用。我添加了一个额外的val db = DriverManager.getConnection(url, username, pw); 进行测试。 (异常内部失败的函数)这很好用。

另一个有趣的细节。如果我删除 %dep 块和类行,则会产生第一个块非常相似的错误。相同的错误信息;相同的函数+失败的行号,但函数堆栈有点不同。

我在这里找到了源代码:http://code.metager.de/source/xref/openjdk/jdk8/jdk/src/share/classes/java/sql/DriverManager.java

我的问题在第 689 行。所以如果所有参数都正常,可能是来自isDriverAllowed() 检查?

【问题讨论】:

  • 你遇到的问题是 Zeppelin 没有为 Postgres 加载 jdbc 驱动。你用的是什么版本的 zeppelin?
  • 我正在使用“zeppelin-0.5.6”。但是为什么第一个块能够访问数据库而第二个块不工作?这感觉就像 z.load() 函数将 jdbc 添加到从 JdbcRDD() 函数搜索并被 sqlContext.read.jdbc() 函数忽略的列表中。
  • 您可以尝试执行以下操作吗:在您的解释器配置中,添加以下属性:spark.driver.extraClassPath,其值为 /data/extraJarFiles/postgresql-9.4.1208.jar。您可以通过单击 Zeppelin 的顶部横幅访问解释器配置 --> 解释器
  • 这个额外的行只是以一个新的错误消息结束。 org.apache.spark.SparkException: Found both spark.driver.extraClassPath and SPARK_CLASSPATH. Use only the former. 我没有在任何地方设置这个值,但是在日志中找到了 SPARK_CLASSPATH,所以它必须是启动过程的一部分。我在第一篇文章中添加了更多细节。
  • 检查 spark-env.sh 和 zeppelin-env.sh 并注释 SPARK_CLASSPATH 行

标签: java scala apache-spark scalar apache-zeppelin


【解决方案1】:

我在 Zeppelin 中的依赖项也遇到了同样的问题,我必须将我的 jar 添加到 zeepelin-env.sh 中的 SPARK_SUBMIT_OPTIONS 以将它们包含在所有笔记本和段落中

所以在 zeppelin-env.sh 中你将 SPARK_SUBMIT_OPTIONS 修改为:

export SPARK_SUBMIT_OPTIONS="--jars /data/extraJarFiles/postgresql-9.4.1208.jar

然后你必须重启你的 zeppelin 实例。

【讨论】:

  • 你能提出你的解决方案吗?您所说的“Zeppelin 可以与 spark 通信,或者可以在独立模式下自行完成所有工作”是什么意思?
  • 这不是我案例的正确答案,但它引导我找到了解决方案。 Zeppelin 可以与 spark 通信,也可以在独立模式下自行完成所有工作。参数 SPARK_SUBMIT_OPTIONS 仅与 Spark 结合使用。我的小测试环境在独立模式下运行,所以它忽略了参数。但是有了 Zeppeelin 正在调用其他程序的提示,我可以用一个简单的ps -efH 命令来跟踪它。 Zeppelin 正在执行interpreter.sh,这又在调用Java。所以我将我的 JAR 文件从使用的类路径移到了一个文件夹中,一切正常。
  • 正是... 解释器进程,对于 spark 解释器来说,就是 spark 进程。就像你在做 spark-shell 一样。
  • 关于问题:您可以安装 Zeppelin 而不需要任何额外的软件(没有 Spark / 没有 Hadoop)。因此,您只需下载该软件并将其解压缩到一个文件夹中,它就可以运行了。因此,您可以在使用集成 Spark 解释器的第一次测试时使用此设置。但看起来与完整设置相比,系统的行为有点不同。例如%dep 块中的参数未提交给子 java 进程。 interpreter.sh 中的代码显示了不同的方式。
【解决方案2】:

就我而言,在执行 spark/scala 代码时,我收到了同样的错误。我之前在我的 spark-env.sh conf 文件中设置了 SPARK_CLASSPATH - 它指向一个 jar 文件。我删除/注释掉了 spark-env.sh 中的行并重新启动了 zepplin。这消除了错误。

【讨论】:

    猜你喜欢
    • 2016-03-21
    • 2019-07-14
    • 2018-09-29
    • 1970-01-01
    • 1970-01-01
    • 2023-01-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多