在pyspark中使用jdbc jar

时间:2016-03-31 06:48:41

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

我需要从pyspark中的postgres sql数据库中读取。 我知道在herehere和许多其他地方之前已经问过这个问题,但是,那里的解决方案要么在本地运行目录中使用jar,要么手动将其复制到所有工作者。

我下载了postgresql-9.4.1208 jar并将其放在/ tmp / jars中。然后我继续使用--jars和--driver-class-path开关调用pyspark:

pyspark --master yarn --jars /tmp/jars/postgresql-9.4.1208.jar --driver-class-path /tmp/jars/postgresql-9.4.1208.jar

在pyspark里面我做了:

df = sqlContext.read.format("jdbc").options(url="jdbc:postgresql://ip_address:port/db_name?user=myuser&password=mypasswd", dbtable="table_name").load()
df.count()

然而,虽然使用--jars和--driver-class-path对我创建的jar工作正常,但jdbc失败了,我从工作者那里得到了一个例外:

 java.lang.IllegalStateException: Did not find registered driver with class org.postgresql.Driver

如果我手动将jar复制到所有worker并添加--conf spark.executor.extraClassPath和--conf spark.driver.extraClassPath,它确实有效(使用相同的jar)。 documentation btw建议使用不推荐使用的SPARK_CLASSPATH实际上会添加这两个开关(但是会产生副作用,阻止使用我需要做的--jars选项添加其他jar)

所以我的问题是:jdbc驱动程序的特殊之处在于它无法正常工作,如何在不必手动将其复制到所有工作程序的情况下添加它。

更新:

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

问题是我似乎无法找到computer_classpath.sh,也不了解原始类加载器的含义。

我确实找到this,这基本上解释了这需要在本地完成。 我还发现this基本上说有一个修复,但它在版本1.6.1中尚不可用。

3 个答案:

答案 0 :(得分:4)

我找到了一个有效的解决方案(不知道它是否是最好的解决方案)。 显然,如果我添加选项:driver =“org.postgresql.Driver”,这可以正常工作。即我的全线(在pyspark内)是:

df = sqlContext.read.format("jdbc").options(url="jdbc:postgresql://ip_address:port/db_name?user=myuser&password=mypasswd", dbtable="table_name",driver="org.postgresql.Driver").load()
df.count()

另一件事:如果您已经在使用自己的胖罐(我在我的完整应用程序中),那么您需要做的就是将jdbc驱动程序添加到您的pom文件中:

    <dependency>
      <groupId>org.postgresql</groupId>
      <artifactId>postgresql</artifactId>
      <version>9.4.1208</version>
    </dependency>

然后您不必将驱动程序添加为单独的jar,只需使用带有依赖项的jar。

答案 1 :(得分:0)

您正在查看哪个版本的文档? 似乎compute-classpath.sh已被弃用了一段时间 - 从Spark 1.3.1开始:

$ unzip -l spark-1.3.1.zip | egrep '\.sh' | egrep classpa
 6592  2015-04-11 00:04   spark-1.3.1/bin/compute-classpath.sh

$ unzip -l spark-1.4.0.zip | egrep '\.sh' | egrep classpa

什么都不产生。

我认为您应该使用load-spark-env.sh来设置类路径:

$/opt/spark-1.6.0-bin-hadoop2.6/bin/load-spark-env.sh

并且您需要在$SPARK_HOME/conf/spark-env.sh文件中设置SPARK_CLASSPATH(您将从模板文件$SPARK_HOME/conf/spark-env.sh.template复制)。

答案 2 :(得分:0)

我认为这是此处描述和解决的问题的另一种表现形式:https://github.com/apache/spark/pull/12000。我在3周前撰写了这个修复程序并且没有任何动作。也许如果其他人也表达了他们受到影响的事实,那可能会有所帮助吗?