3

我需要从 pyspark 中的 postgres sql 数据库中读取数据。我知道之前已经问过这个问题,例如这里这里和许多其他地方,但是,那里的解决方案要么使用本地运行目录中的 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 复制到所有工作人员并添加 --conf spark.executor.extraClassPath 和 --conf spark.driver.extraClassPath,它确实有效(使用相同的 jar)。顺便说一句,文档建议使用已弃用的 SPARK_CLASSPATH 实际上添加了这两个开关(但具有防止使用我需要做的 --jars 选项添加其他 jars 的副作用)

所以我的问题是:jdbc 驱动程序有什么特别之处使它无法工作,如何添加它而无需手动将其复制给所有工作人员。

更新:

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

问题是我似乎找不到 computer_classpath.sh 也不明白原始类加载器的含义。

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

4

3 回答 3

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()

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

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

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

于 2016-03-31T08:57:39.057 回答
0

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

$ 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)。

于 2016-03-31T07:52:32.820 回答
0

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

于 2016-04-13T14:04:11.703 回答