我有以下简单的代码,用于将Postgres数据库中的表加载到RDD中。
# this setup is just for spark-submit, will be ignored in pyspark
from pyspark import SparkConf, SparkContext
from pyspark.sql import SQLContext
conf = SparkConf().setAppName("GA")#.setMaster("localhost")
sc = SparkContext(conf=conf)
sqlContext = SQLContext(sc)
# func for loading table
def get_db_rdd(table):
url = "jdbc:postgresql://localhost:5432/harvest?user=postgres"
print(url)
lower = 0
upper = 1000
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", "password") \
.load()
ret = ret.rdd
return ret
# load table, and print results
print(get_db_rdd("mytable").collect())
我运行./bin/pyspark
然后将其粘贴到解释器中,并按预期从我的表中打印出数据。
现在,如果我将该代码保存到名为test.py
的文件然后执行./bin/spark-submit test.py
,它就会开始运行,但之后我会看到这些消息永远发送到我的控制台:
17/02/16 02:24:21 INFO Executor: Running task 45.0 in stage 0.0 (TID 45)
17/02/16 02:24:21 INFO JDBCRDD: closed connection
17/02/16 02:24:21 INFO Executor: Finished task 45.0 in stage 0.0 (TID 45). 1673 bytes result sent to driver
编辑:这是在一台机器上。我没有开始任何主人或奴隶; spark-submit
是我在系统启动后运行的唯一命令。我尝试使用相同的结果进行主/从设置。
我的spark-env.sh
文件如下所示:
export SPARK_WORKER_INSTANCES=2
export SPARK_WORKER_CORES=2
export SPARK_WORKER_MEMORY=800m
export SPARK_EXECUTOR_MEMORY=800m
export SPARK_EXECUTOR_CORES=2
export SPARK_CLASSPATH=/home/ubuntu/spark/pg_driver.jar # Postgres driver I need for SQLContext
export PYTHONHASHSEED=1337 # have to make workers use same seed in Python3
如果我点火提交一个只从列表或其他东西创建RDD的Python文件,它就有效。我尝试使用JDBC RDD时只遇到问题。我错过了什么?
答案 0 :(得分:1)
使用spark-submit
时,您应该向执行者提供jar
。
要开始使用,您需要为您提供JDBC驱动程序 spark类路径上的特定数据库。例如,要连接到 来自Spark Shell的postgres,您将运行以下命令:
bin/spark-shell --driver-class-path postgresql-9.4.1207.jar --jars postgresql-9.4.1207.jar
注意:同样适用于
spark-submit
命令
<强>疑难解答强>
JDBC驱动程序类必须对原始类加载器可见 在客户端会话和所有执行程序上。这是因为Java的 DriverManager类执行安全检查,导致它忽略 一个人去的时候,所有的驱动程序对原始类加载器都不可见 打开连接。 一种方便的方法是修改 所有工作节点上的 compute_classpath.sh包含您的驱动程序JAR。
答案 1 :(得分:0)
这是一个可怕的黑客。我不是在考虑这个答案,但确实有效。
好吧,只有pyspark有效吗?好的,我们会用它。写了这个Bash脚本:
cat $1 | $SPARK_HOME/bin/pyspark # pipe the Python file into pyspark
我在提交作业的Python脚本中运行该脚本。另外,我包含了用于在进程之间传递参数的代码,以防它帮助某人:
new_env = os.environ.copy()
new_env["pyspark_argument_1"] = "some param I need in my Spark script" # etc...
p = subprocess.Popen(["pyspark_wrapper.sh {}".format(py_fname)], shell=True, env=new_env)
在我的Spark脚本中:
something_passed_from_submitter = os.environ["pyspark_argument_1"]
# do stuff in Spark...
我觉得Spark更好地受到支持,并且(如果这是一个错误)Scala的错误少于Python 3,所以这可能是现在更好的解决方案。但是我的脚本使用了我们在Python 3中编写的一些文件,所以......