缘起
一切都是因为穷,穷则思变
前言
公司赶大潮,组建了一套大数据集群服务器,ELK+Spark组合。但是因为资源倾斜,其实并没有给到靠谱的硬件资源。两台硬件服务器,一台华为3手服务器(6年前买的2手,两年前从老机房拉回来),一台戴尔服务器2手服务器。
在上面基础上用vsphere虚拟化了六台虚机,3台es,3台spark,中间夹杂着web服务器,logstash,mysql等软件。刚开始Es集群动不动就挂,为啥,热死了,没法安装独立空调,那就加风扇吧。
Es稳定后,开始折腾spark。由于spark是高内存应用场景,再结合数据挖掘运算对cpu的高强度运算需求,以及大量数据读写的磁盘需求,导致真实任务开跑的时候,cpu和内存的负载以及磁盘读写的负载都是好几倍的压力。到这里,其实就剩下淡淡的忧伤了。
思来想去,辗转反侧,某一天晚上,灵光一闪,要不把spark从虚机上拿了下来,放到PC上试试,任务走local模式?
说干就干,从其他机器上匀了个4G内存条,配置升级到12G,配合着I5的处理器,应该要比服务器上运行顺畅吧,最起码,减轻虚拟机环境下cpu和内存的竞争,保证了spark内存和cpu的使用是独立资源配置。
正文
运行环境:win10+spark-2.1.0
在此过程中,前后解决以下五个问题:
1、win10下spark运行环境的配置
此处操作流程和遇到的问题主要参考如下链接:
https://blog.csdn.net/qq_24852439/article/details/103064668
2、spark任务提交脚本spark-submit.bat 在win10下执行异常
spark针对windows环境下的脚本执行中参数中有引号的情况进行了判断和处理,但是通过debug和操作系统欺骗(直接修改系统环境,只能往前多走一步,后面还会卡住,达不到最终目标),发现这段处理逻辑官方代码似乎有问题,导致在提交job的时候总是报错(而且是乱码异常,根本无法跟踪),最后通过下载spark-launcher_2.11-2.2.1.jar源码,注释相关业务逻辑,重新打jar包替换得以解决。
具体流程排查流程截图如下:
切入点
spark提交任务时候的参数,注意红框中里面的引号,就是spark执行时候处理后的结果
跟入 org.apache.spark.launcher.SparkLauncher:
需要注释的代码段:
重新编译SparkLauncher的时候,由于会有类的引用,导致重新编译失败,此时需要cmd命令行进入SparkLauncher所在的包,使用如下命令编译:
javac *.java
至此,spark总算稳定在win10的环境下丝滑的运行了起来。开始解决第三个需求
3:job执行所用到的class清理问题
Linux环境下,可以直接在spark-env.sh文件下添加如下配置解决历史job导致的磁盘空间占用问题:
export SPARK_WORKER_OPTS="-Dspark.worker.cleanup.enabled=true -Dspark.worker.cleanup.appDataTtl=3600 "
在win10环境下,没有参考上面的配置,local模式下所有的job执行目录都在%TEMP%,所以直接清理temp目录对应的jar文件即可。最终,是直接使用任务计划程序+批处理脚本来清理:
脚本内容:
forfiles /p %TEMP% /s /m xxx.jar -d -1 /c "cmd /c del /f @path"
4:job运行历史结果查看:
起初在linux集群运行的时候,可以很方便的查看历史job执行数据,但是在win10下只能在任务执行的时候查看,只要job跑完,就没法查看历史任务。
所以最初的想法是通过在代码中添加日志监控,通过设定日志级别(error),把job执行结果日志输出到指定文件来处理。但是在测试验证的过程中发下,spark的日志输出会覆盖项目自定义的logback.xml里面的配置,最终导致指定日志级别的日志输出和大量的普通日志混杂到一起,无法简洁分析处理,至此,也没再往下深入了,直接改变思路,从而引出如下第五个问题。
5:如何在windows下启动spark hisotry job 并通过webui浏览历史任务执行结果
查看spark解压缩文件夹的bin目录和sbin目录,所有history job相关的脚本,都是sh,也即都是在linux下可执行的内容,网上搜索许久未果,最后直接阅读linux脚本内容,通过跟踪脚本执行流程和最终启动的服务类,手动改造和定制windows版本的启动服务脚本。具体流程如下:
跟踪linux his启动脚本:
定位最终启动的主类:org.apache.spark.deploy.history.HistoryServer
定位主类启动需要的参数:
Step1:
Step2:
Step3:
Step4:定位window下启动class需要的参数:
脚本跟踪完毕后,思路也就清晰了,对应的,构造windows环境执行脚本即可,具体执行如下操作:
1:在spark bin目录新建bat文件(名字可随意指定比如start-hisotry.bat),输入以下内容:
cmd /V /E /C "%~dp0spark-class.cmd" org.apache.spark.deploy.history.HistoryServer %*
pause
注:增加pause 是用来定位异常使用,刚开始总报错,屏幕一闪就没了,报错内容如下:
File file:/tmp/spark-events does not exist
解放决方案:在/tmp/下创建spark-events文件夹即可。也就是spark解压后文件夹所在根目录的tmp文件夹下面新建spark-events目录,tmp目录之前就有,因为在windows下跑spark的话会需要做一些配置属于hive,这些配置会自动生成tmp目录。
2:在提交job的醒目执行环境参数里面增加如下配置(项目是springBoot,配置在application.yml中):
spark.eventLog.enabled: true
#如果为true,会压缩成lz4格式
spark.eventLog.compress: false
spark.eventLog.dir: D:\tmp\spark-events
#端口号即是最后服务启动时候的监控端口
spark.history.ui.port: 18080
如果是单次任务执行,可直接在任务执行的命令里面加入上面参数即可。
配置完毕,启动start-hisotry.bat,运行job,最终执行效果如下入展示:
至此,本次spark在windows下执行所需要处理的问题都逐一得到了解决,通过本次持续的跟踪,也算是对spark的执行流程有了相对深入的了解,但有的地方也可能有问题,也有可能在新版本中以上的问题都可能不存在了,如果你有想法,欢迎交流。
参考:
https://www.cnblogs.com/yumengfei/p/12028920.html