情景描述
情景为在本地的Pycharm上配置了SSH远程解释器,等于是在本地开发,同步提交到远程服务器上执行,十分便捷。跟着教学视频在构建一个小demo时却遇到了几个视频中未曾出现的问题,在此记录下来。先前已经测试过远程服务器上pyspark交互式环境和spark-submit命令均可正常运行。
1. 问题一
报错:JAVA_HOME not set.
最初我以为是需要在配置解释器的用户的.bashrc文件中配置JAVA_HOME,但尝试后无效。在网上看到的另一个解决方案是将JAVA_HOME配置到spark安装目录下的sbin/spark-config.sh文件中,尝试后也无效。网上的资料中有效的是以下这个方案:在本地的py文件中加入了以下的代码(JAVA_HOME中配置远程服务器上的jdk安装路径)。
import os
os.environ['JAVA_HOME'] = "/export/server/jdk1.8.0_241"
2. 问题二
程序在执行完spark的初始化(以下几行代码)后直接退出,后面的代码都无法执行。
if __name__ == '__main__':
# 初始化执行环境,构建SparkContext对象
conf = SparkConf().setAppName("test").setMaster("local[3]")
sc = SparkContext(conf=conf)
和视频中的输出进行比较,发现少了“Using Spark’s default log4j profile: org/apache/spark/log4j-defaults.properties”这句输出,由此想到问题可能是找不到spark的位置,网上的资料中也有说添加SPARK_HOME的方案,尝试后奏效:在本地的py文件中加入了以下的代码(SPARK_HOME中配置spark的安装路径)。
os.environ['SPARK_HOME'] = "/export/server/spark-3.2.0-bin-hadoop3.2"
3. 问题三
报错:Exception:Python in worker has different version 3.6 than that in driver 3.8.
注意到是版本问题,我首先想到了在创建虚拟环境时没有指定python的版本,于是尝试了重新创建了虚拟环境并指定了python版本,但是仍会出现这个错误。网上的资料中有效的是以下这个方案:在本地的py文件中加入了以下的代码(PYSPARK_PYTHON中配置虚拟环境中的python解释器路径)。
import os
os.environ['PYSPARK_PYTHON'] = '/export/software/anaconda3/envs/pyspark/bin/python'
4. 问题四
在解决上述三个问题后,遇到了如下的报错。
这个问题在网上没有搜到,开始我非常奇怪,因为一般都能搜到,随后就和视频里对比区别在哪里,然后发现视频中安装的pyspark是3.2.0版本,和spark的版本是对应的,而我安装时pyspark自动安装的是最新的3.3.0版本,由此产生了不一致,重新安装3.2.0版本的pyspark,成功解决了该问题。
感想
像问题四这种非常个性化的问题很可能和版本有关,某一个小的地方更新了就可能报错,软件版本(如:spark)和类库版本(如:pyspark)需要保持一致。而从前三个问题可以看出这种远程提交代码执行的方式似乎无法访问服务器中的环境变量,所以需要在程序中显式地指定出来。