【发布时间】:2017-04-21 19:59:28
【问题描述】:
我之前在自己的 Linux 服务器上使用 Apache Spark 和 PostgreSQL JDBC 驱动程序没有问题,但我无法让它在 Amazon EMR 上以同样的方式工作。
我首先下载了 Postgres 驱动程序并以这种方式设置了我的 pyspark 类路径:Adding postgresql jar though spark-submit on amazon EMR
我在使用 Spark 设置的 Amazon EMR 实例上在 pyspark 中执行了以下操作,类似于我通常在自己的服务器上执行的操作。 “myhost”是我运行 PostgreSQL 的 Amazon RDS 实例的主机名,我可以使用 psql 从我的 EMR 实例连接到它,所以我知道它应该可以工作:
# helper, gets RDD from database
def get_db_rdd(table, lower=0, upper=1000):
db_connection = {
"host": "myhost",
"port": 5432,
"database": "mydb",
"user": "postgres",
"password": "mypassword"
}
url = "jdbc:postgresql://{}:{}/{}?user={}".format(db_connection["host"],
db_connection["port"],
db_connection["database"],
db_connection["user"])
ret = sqlContext \
.read \
.format("jdbc") \
.option("url", url) \
.option("dbtable", table) \
.option("partitionColumn", "id") \
.option("numPartitions", 1024) \
.option("lowerBound", lower) \
.option("upperBound", upper) \
.option("password", db_connection["password"]) \
.load()
ret = ret.rdd
return ret
from pyspark.sql import SQLContext
sqlContext = SQLContext(sc)
rdd = get_db_rdd("test", 0, 3) # table exists, has columns (`id bigserial, string text`)
我立即遇到这个异常的崩溃:
17/04/21 19:34:07 ERROR Schema: Failed initialising database.
Unable to open a test connection to the given database. JDBC url = jdbc:derby:;databaseName=metastore_db;create=true, username = APP. Terminating connection pool (set lazyInit to true if you expect to start your database after your app). Original Exception: ------
java.sql.SQLException: Failed to start database 'metastore_db' with class loader org.apache.spark.sql.hive.client.IsolatedClientLoader$$anon$1@3aa157b0, see the next exception for details.
at org.apache.derby.impl.jdbc.SQLExceptionFactory.getSQLException(Unknown Source)
at org.apache.derby.impl.jdbc.SQLExceptionFactory.getSQLException(Unknown Source)
[...]
在网上环顾四周,这与 Apache Hive 有关...不知道为什么会涉及到这里,但我可能会误解。我确实在我的家庭目录中看到了metastore_db。所有建议的解决方案都涉及编辑一些我什至没有在我的实例上的 Hive 配置或创建我已经拥有的目录。我的 EMR 实例具有完全默认设置。更熟悉这种环境的人能否为我指明正确的方向?
编辑:我手头没有完整的堆栈跟踪,但在我的 GNU 屏幕上还剩下一些。这里还有更多,提到德比:
Caused by: ERROR XJ040: Failed to start database 'metastore_db' with class loader org.apache.spark.sql.hive.client.IsolatedClientLoader$$anon$1@3aa157b0, see the next exception for details.
at org.apache.derby.iapi.error.StandardException.newException(Unknown Source)
at org.apache.derby.impl.jdbc.SQLExceptionFactory.wrapArgsForTransportAcrossDRDA(Unknown Source)
... 113 more
Caused by: ERROR XSDB6: Another instance of Derby may have already booted the database /home/hadoop/metastore_db.
at org.apache.derby.iapi.error.StandardException.newException(Unknown Source)
at org.apache.derby.iapi.error.StandardException.newException(Unknown Source)
at org.apache.derby.impl.store.raw.data.BaseDataFileFactory.privGetJBMSLockOnDB(Unknown Source)
编辑 2:使用其他 RDD,如下所示:sc.parallelize([1, 2, 3]).map(lambda r: r * 2).collect()。问题只针对连接到 Postgres 的 RDD。
编辑 3:
>>> spark.range(5).show()
+---+
| id|
+---+
| 0|
| 1|
| 2|
| 3|
| 4|
+---+
【问题讨论】:
-
"Failed to start database 'metastore_db'" 通常发生在您已经运行了一个 Spark 实例并且假设默认元存储在幕后使用 Derby 因此例外。你能发布整个堆栈跟踪吗?我预计 Derby 会在堆栈跟踪的底部出现错误。
-
是的,我看到了 Derby 的错误。但据我所知,我只运行了一个 Spark 实例。星期一,我会再试一次,并捕获整个堆栈跟踪。
-
越来越好!认为我们可以很快解决它。我敢肯定,当您只需
spark-shell并执行spark.range(5).show并启动 Spark 底层基础架构时,您将获得完全相同的堆栈跟踪。 -
感谢您的帮助。我今天终于尝试了,不认为这是问题所在。如果我只是执行
sc.parallelize([1, 2, 3]).map(lambda r: r * 2).collect()之类的操作,它会起作用并返回结果。只有当 JDBC 驱动程序涉及我的 Postgres 源 RDD 函数时才会出现问题。这是整个回溯(很大):gist.github.com/anonymous/15775cc6fea23bad63150a7f30b091ab -
我认为我设置 Postgres 连接的方式,由于某种原因,它试图再次连接到我的
metastore_db,但我的 Spark 实例已经在使用它,所以它会引发异常.
标签: postgresql apache-spark amazon-emr