【发布时间】: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