我需要从 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 也不明白原始类加载器的含义。