问题描述
本人在学习spark的时候,尝试做了一个数据仓库小项目,内容大致为从SQL和hive中分别提取一些表进行数据分析,在hive中建立ODS,DWD,DWS,ADS层,最后再把结果数据写入MySQL中。代码在Windows本地测试都没有问题,最后打成jar包上传至dolphinscheduler运行上屡屡出现奇怪的问题。最终经过仔细排查,解决了问题,于是把过程仔细记录下来。
问题解决
我在测试途中,先没有把sparkBaseConfig的master改成yarn,动态分配也没有加入。只用local[*]的模式测试运行一下,在解决昨天遇到的找不到SPARK_HOME2环境变量后,成功运行。
当我把代码进行修改,重新打包,使用yarn运行,并打开动态分配。
val spark: SparkSession = SparkFactory()
.build()
.baseConfig("ebs_01","yarn")
.optimizeDriver()
.optimizeExecutor()
.optimizeLimit()
.optimizeSerializer()
.optimizeNetAbout()
.optimizeDynamicAllocation(true)
.optimizeShuffle()
.optimizeSpeculation(true)
.optimizeRuntime(adaptiveEnabled = true,cboEnabled = true)
.warehouseDir("hdfs://single01:9000/hive312/warehouse")
.end()
调度器报错了,原因是找不到类
我把打完的jar包打开看了一下,确实没有这个类,不仅如此,我的代码甚至没有被编译成.class文件,但是在把master改成yarn前的代码,是有被编译成.class的,类都是有的。
之前的jar包:
改后的jar包:
仅仅改动几行代码会导致打包失败?按理来说不应该有关联吧。
仔细排查后发现,我的Maven环境缺少了scala-maven-plugin依赖,所以本身就是没法编译,无法正常打jar包的,那么之前能打成正常的jar包,反而变的奇怪了。
<plugin>
<groupId>net.alchim31.maven</groupId>
<artifactId>scala-maven-plugin</artifactId>
<version>4.3.1</version>
<executions>
<execution>
<goals>
<goal>compile</goal>
<goal>testCompile</goal>
</goals>
</execution>
</executions>
</plugin>
研究一段时间发现,这与maven打包插件的机制有关,因为我在写代码的时候,使用的local是一直在运行测试的,运行测试的过程中就会产生编译后的.class文件,maven在打包的时候,如果有target的文件,是直接把tartget里编译好的写入jar包里的,如果没有,maven才会重新编译打包。没有那个scala-maven插件,我的maven是无法正常编译的,但是idea可以编译。最终造成了这样奇怪的现象。
加完插件后,成功打出正常的jar包。
本以为万事大吉,结果又出问题了。
shuffle.service.enabled没有开启,我在代码中肯定是已经写的了,所以就是环境没有配置好了。在网上找了一些帖子后,发现我虚拟机上的 hadoop-3.1.3/etc/hadoop/yarn-site.xml中需要配置如下内容:
配完之后,竟然找不到org.apache.spark.network.yarn.YarnShuffleService这个类,我缺少spark-3.1.2-yarn-shuffle.jar这个包!!最神奇的是maven仓库居然找不到这个包。
那它在哪里?只能自己继续研究寻找一下,结果发现它在spark的目录里有一个yarn目录里有......
把它拷贝到 hadoop-3.1.3/share/hadoop/yarn/lib下
cp spark-3.1.2-yarn-shuffle.jar /opt/software/hadoop-3.1.3/share/hadoop/yarn/lib
重启服务后,再进入调度器运行,终于可以正常运行了。
它要是再不好,我都要红温了。这踩的坑一个接一个,一个比一个奇怪。以前觉得写代码痛苦,现在想想觉得运维更是痛苦,时常容易高血压。