Spark - 集群与本地提交Spark任务问题记录

在平时的 Spark 开发中,若要将代码提交到 Spark 集群中,就必须打包,然后上传。这样非常繁琐,不方便调试,所以想着在本地调试将任务提交上Spark集群,记录一下连条过程遇到的问题。

正确配置

集群Scala版本:2.12.10

Spark集群版本:3.0.1

Pom文件

这里导入的Scala版本的Spark版本必须与集群一致,本地环境配置的Scala版本也必须和集群一致,可以启动spark-shell查看scala的版本。

问题

问题一:一开始遇到问题的是SparkSession提交任务到集群时,Driver启动在本地,想着把Driver启动到虚拟机的集群上面,但是conf设置Driver的IP地址、包括地址映射主机名都没有成功,Driver还是只能指定本机的IP地址(与Spark集群同一网段的IP)启动在本地进程上。

问题截图:

问题二:解决完问题一的Driver启动位置问题后,又遇到一个关于序列化的问题(serialVersionUID)

 一开始在CDSN上找问题,在类里边直接写死了一个serialVersionUID,但是无效

思来想去以为是本地环境的JDK和集群依赖的JDK不一致,导致序列化方式不一致,所以Driver序列化下发资源文件到Worker手里时,Worker无法反序列化。

然后想着还是从Driver入手,把Driver运行在集群上应该没什么问题,结果就是换不了Driver执行的IP

最后发现是Spark集群依赖的Scala版本和我本地的Scala版本不一致。。。。

集群是2.12.10,而我的是2.12.16。。。

更改本地的Scala版本后,提交任务正常。。SparkSession终于走到了读取数据源的那一步

问题三:试着去读取一份Json文件(放在本地环境),但是SparkSession一直找不到这个文件,报错FileNotFound,然后我在服务器上启动了本地线程模式的Spark集群读取Json文件,读取没问题。然后切换成Standalone集群模式启动读取本地的Json文件,蛤蛤读不了。最后将文件路径替换成Hdfs的路径,把Json文件放到Hdfs上面,读取成功,解决。

最后附上Connection测试代码:

SparkConf sparkConf = new SparkConf()
                .setMaster("spark://ip:7077") //master运行的主机端口
                .setAppName("JavaSpark")
                .set("spark.driver.host", "本地ip");  //drivefr运行的本地IP,端口随机分配
SparkSession spark = SparkSession.builder()
                .config(sparkConf)
                .getOrCreate();
Dataset<Row> json = spark.read().format("json")
                   .json("hdfs://namenode:8020/user.json");
json.show();
spark.close();

 成功结果:

后续问题

1、使用UDF函数报错

        在使用UDF函数时,报了个序列化的错误。

 需要指定Jar包路径才能正常加载函数,经测试,在本地调试需要把Jar包打到Hdfs上。打包运行则可以指定在本地。

        两种方式都需要上传,所以测试UDF函数时可以先用  local[*] 模式测试,调试完再上传。这样应该会方便点。

2、Standalone-Cluster模式下读取不到数据

        集群模式默认读取的还是Hdfs,但是还是需要指定hdfs文件系统,否则程序会读本地文件系统,并且还读不到数据。

3、连条Hive

        3.1、hadoop_home not found

        有报这个错误是因为导入的依赖与Hadoop版本不一致。

        3.2、SparkSQL与Hive版本兼容问题

        通过SparkSession去连条需要加入两条依赖,指定元数据服务端口还有数据仓库位置。

        

         一开始连接的是CDH 6.3.2 安装的Hive版本是 2.1.1

        

        配置好以后调用SparkSQL一直报错(在类里找不到  get_table_req 的方法) 

        一看Spark3.x的版本默认支持Hive-2.3.7,试过依赖降级、把CDH上的Hive依赖Jar包下载到本地指定,都没成功而且相对来说比较麻烦,还是对应版本来操作好一点,后来测试连接自己虚拟机的Hive-3.1.2,可以正常连接。

4、SpringBoot集成(序列化问题

java.lang.ClassCastException: cannot assign instance of java.lang.invoke.SerializedLambda to field org.apache.spark.rdd.MapPartitionsRDD.f of type scala.Function3 in instance of org.apache.spark.rdd.MapPartitionsRDD

在之前为SparkSession设置了Jar路径后解决了这个问题(使用UDF),用Springboot的时候又出现了这个问题。        

排查后发现,是打包的问题。Springboot有默认的打包方式,打包的目录结构与自定义的不同,所以在分发Jar包以后,Executor 无法load class。

尝试过自定义打包Springboot项目,也尝试过spring-boot-maven-plugin的repackage,但是repackage的jar包没带依赖。

解决:多打了一个maven-shade-plugin的包,用于SparkSession读取。

参考链接:记一次奇妙的 spring-boot + spark debug 经历 - Phantom01 - 博客园

5、本地SparkSQL连接远程Hive调试

本地模式运行SparkSQL连接远程Hive遇到的问题:

        HADOOP_HOME and hadoop.home.dir are unset。

解决方案:

        不需要在windows搭建Hadoop,需要下载winutils-master.zip,并配置环境变量,将文件夹中对应的Hadoop版本bin下的hadoop.dll文件复制到C盘下的Windows\System32下,然后运行程序,若不生效则重启IDEA,若还不生效则重启电脑。

可见虚拟机中的Hdfs系统生成了本地用户的任务缓存文件夹(成功)

即可在本地sparksql程序中远程调用Hive

注意:pom.xml文件中导入的hdfs依赖版本需一致

 参考链接:HADOOP_HOME and hadoop.home.dir are unset 报错处理_一念永恒的博客-CSDN博客_hadoop_home

 

        

        

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值