资讯动态

Windows下搭建Spark 2.4.8开发环境:IDEA 2020.1 + Maven 3.6.3 + Scala 2.11.8完整指南

发布时间:2026/10/20 6:30:07 来源:尧图企业网站定制
1. 为什么在2024年还要折腾这套老版本环境先把结论摆在前面这套组合IDEA 2020.1社区版 Maven 3.6.3 Scala 2.11.8不是随便凑的它对应的是Spark 2.x时代的经典生产栈。很多公司内部的数据平台、离线任务调度系统至今还跑在Spark 2.4.x上而Spark 2.4.x官方编译时绑定的就是Scala 2.11.8。你要是拿Scala 2.12或2.13去配编译期就会撞上NoSuchMethodError或者IncompatibleClassChangeError这类让人抓狂的二进制不兼容问题。所以这篇文章的目标读者很明确一是学校里做大数据课程设计、需要跑通Spark本地模式的同学二是刚进公司、被分配去维护老Spark任务的开发者三是想在自己Windows笔记本上搭一套能写、能跑、能调试的Spark开发环境而不是每次改一行代码就打包丢到集群上试的人。Windows下搭这套环境坑比Linux多得多。核心矛盾在于Spark和Hadoop生态原生是为Linux设计的Windows上缺winutils.exe、缺hadoop.dll路径分隔符还不一样。我见过太多人卡在java.io.IOException: Could not locate executable null\bin\winutils.exe这个报错上一整天。这篇文章会把每个坑的位置、成因、解法都摊开讲清楚让你照着做就能跑通第一个WordCount。整套环境我建议的版本对应关系是这样的组件版本选择理由JDK1.88u系列Spark 2.x只认Java 8Java 11会报模块访问错误Scala2.11.8与Spark 2.4.x二进制绑定版本严格一致Maven3.6.3稳定、与IDEA 2020.1兼容好避免3.8的HTTP仓库拦截问题IDEA2020.1社区版社区版免费Scala插件支持完善Spark2.4.82.4.x最后一个稳定版Scala 2.11.8编译注意版本不是越新越好。Scala的小版本2.11.x之间二进制兼容但2.11和2.12之间不兼容。Spark官方下载页会明确标注Pre-built for Apache Hadoop 2.7 and later对应的Scala版本选之前一定看清楚。2. 环境搭建前的整体思路与选型拆解2.1 为什么用Maven而不是SBTScala圈子里SBT是亲儿子但Spark项目里Maven反而是主流。原因有几个第一Spark源码本身就是Maven构建的看官方pom.xml能直接抄依赖配置第二公司里Java和Scala混编的项目多Maven对混合编译的支持更成熟第三Maven的依赖树、仓库镜像配置对新手更友好出问题好排查。SBT的问题在于它的依赖解析逻辑和Maven不同第一次拉依赖经常卡在Resolving上而且国内镜像配置比Maven麻烦。对于我只想赶紧跑通一个Spark任务的需求Maven是更稳的选择。2.2 为什么IDEA用社区版就够IDEA Ultimate版确实对Spring、数据库支持更好但写Spark用不上那些。社区版装个Scala插件代码补全、跳转、调试、Maven集成全都有。唯一的小遗憾是社区版没有内置的Database工具窗口但Spark开发阶段你基本用命令行或外部工具连数据库影响不大。2.3 环境变量的设计逻辑Windows下这套环境需要配三个关键环境变量JAVA_HOME、SCALA_HOME、HADOOP_HOME。前两个好理解HADOOP_HOME是很多人忽略的——Spark在Windows上跑本地模式时会通过HADOOP_HOME去找winutils.exe和hadoop.dll没有它就直接抛异常。路径里绝对不要有空格和中文。我见过有人把JDK装在C:\Program Files\Java\下结果Maven构建时报路径解析错误。统一放到D:\dev\这种纯英文无空格目录下最省心。3. 核心组件安装与配置实操3.1 JDK 1.8的安装与验证去Oracle官网或国内镜像站下载jdk-8uXXX-windows-x64.exe。安装时自定义路径比如D:\dev\jdk1.8.0_XXX。装完配环境变量JAVA_HOME D:\dev\jdk1.8.0_XXX Path 追加 %JAVA_HOME%\bin验证java -version输出里必须看到1.8.0_XXX。如果显示的是别的版本说明系统里还有别的JDKPath顺序需要调整把%JAVA_HOME%\bin放到最前面。实操心得Windows上经常出现装了新JDK但java -version还是旧的的情况根源是C:\ProgramData\Oracle\Java\javapath这个目录被系统自动加到了Path最前面。把这个目录从Path里删掉或者把%JAVA_HOME%\bin提到它前面。3.2 Scala 2.11.8的安装去Scala官网下载scala-2.11.8.msi安装到D:\dev\scala-2.11.8。配环境变量SCALA_HOME D:\dev\scala-2.11.8 Path 追加 %SCALA_HOME%\bin验证scala -version应该输出Scala code runner version 2.11.8。这里有个细节Scala 2.11.8需要Java 8如果你系统默认Java是11scala命令会报错。所以JDK版本一定要先确认好。3.3 Maven 3.6.3的安装与国内镜像配置下载apache-maven-3.6.3-bin.zip解压到D:\dev\apache-maven-3.6.3。配环境变量MAVEN_HOME D:\dev\apache-maven-3.6.3 Path 追加 %MAVEN_HOME%\bin关键一步是配置国内镜像否则拉依赖能慢到让你怀疑人生。编辑D:\dev\apache-maven-3.6.3\conf\settings.xml在mirrors标签里加mirror idaliyunmaven/id mirrorOf*/mirrorOf namealiyun maven/name urlhttps://maven.aliyun.com/repository/public/url /mirror同时把本地仓库位置改一下默认在C:\Users\你的用户名\.m2\repositoryC盘紧张的话改到D盘localRepositoryD:\dev\maven-repo/localRepository验证mvn -v输出里要能看到Apache Maven 3.6.3和Java version: 1.8.0_XXX。3.4 Hadoop winutils的配置最容易漏的一步这一步是Windows下Spark环境的命门。去GitHub上搜winutils找对应Hadoop 2.7.x版本的winutils.exe和hadoop.dll。目录结构这样建D:\dev\hadoop-2.7.1\ └── bin\ ├── winutils.exe └── hadoop.dll配环境变量HADOOP_HOME D:\dev\hadoop-2.7.1 Path 追加 %HADOOP_HOME%\bin再把hadoop.dll复制一份到C:\Windows\System32下。这一步不做的话Spark启动时会报UnsatisfiedLinkError。注意winutils.exe的版本要和你的Hadoop版本对应。Spark 2.4.8默认绑Hadoop 2.7那就找2.7.x的winutils。版本不匹配会出现权限相关的诡异报错。3.5 IDEA 2020.1社区版与Scala插件安装IDEA社区版一路默认即可。装完后打开File - Settings - Plugins搜索Scala安装后重启。2020.1版本的Scala插件建议用2020.1.x系列别装太新的否则可能和IDEA版本不兼容。重启后新建项目时应该能看到Scala选项。如果看不到检查插件是否真的启用成功。4. 创建第一个Spark Maven项目4.1 项目骨架搭建打开IDEAFile - New - Project选Maven勾选Create from archetype里的org.scala-tools.archetypes:scala-archetype-simple如果没有就选普通Maven项目后面手动加Scala支持。项目建好后目录结构应该是spark-demo\ ├── pom.xml └── src\ ├── main\ │ └── scala\ └── test\ └── scala\如果src/main下没有scala目录手动建一个然后右键Mark Directory as - Sources Root。4.2 pom.xml的完整配置这是整个项目的核心。直接给一份能跑的配置?xml version1.0 encodingUTF-8? project xmlnshttp://maven.apache.org/POM/4.0.0 xmlns:xsihttp://www.w3.org/2001/XMLSchema-instance xsi:schemaLocationhttp://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd modelVersion4.0.0/modelVersion groupIdcom.demo/groupId artifactIdspark-demo/artifactId version1.0-SNAPSHOT/version properties maven.compiler.source1.8/maven.compiler.source maven.compiler.target1.8/maven.compiler.target scala.version2.11.8/scala.version spark.version2.4.8/spark.version encodingUTF-8/encoding /properties dependencies dependency groupIdorg.scala-lang/groupId artifactIdscala-library/artifactId version${scala.version}/version /dependency dependency groupIdorg.apache.spark/groupId artifactIdspark-core_2.11/artifactId version${spark.version}/version /dependency dependency groupIdorg.apache.spark/groupId artifactIdspark-sql_2.11/artifactId version${spark.version}/version /dependency /dependencies build plugins plugin groupIdnet.alchim31.maven/groupId artifactIdscala-maven-plugin/artifactId version3.4.6/version executions execution goals goalcompile/goal goaltestCompile/goal /goals /execution /executions configuration scalaVersion${scala.version}/scalaVersion /configuration /plugin /plugins /build /project几个关键点解释一下spark-core_2.11里的_2.11就是Scala版本后缀写错了拉不到包scala-maven-plugin负责把.scala文件编译成.class没有它Maven根本不认识Scala代码。4.3 写第一个WordCount在src/main/scala下新建com.demo.WordCountpackage com.demo import org.apache.spark.{SparkConf, SparkContext} object WordCount { def main(args: Array[String]): Unit { val conf new SparkConf() .setAppName(WordCount) .setMaster(local[*]) val sc new SparkContext(conf) sc.setLogLevel(WARN) val data sc.parallelize(Seq( hello spark, hello scala, spark is fast, scala is nice )) val result data .flatMap(_.split(\\s)) .map((_, 1)) .reduceByKey(_ _) .collect() result.foreach(println) sc.stop() } }setMaster(local[*])表示本地模式用所有CPU核心。setLogLevel(WARN)是为了屏蔽Spark那一大堆INFO日志不然控制台刷屏看不清结果。4.4 运行与验证右键WordCount.scala选Run WordCount。第一次运行Maven会拉一堆依赖耐心等。跑通后控制台应该输出(scala,2) (spark,2) (hello,2) (is,2) (fast,1) (nice,1)看到这个输出说明整套环境通了。5. 常见报错与排查速查5.1 典型报错对照表报错信息根本原因解决方案Could not locate executable null\bin\winutils.exe没配HADOOP_HOME或winutils缺失配HADOOP_HOME放好winutils.exeNoSuchMethodError: scala.Predef$.$conforms()Scala版本与Spark不匹配确认Scala是2.11.8依赖后缀是_2.11java.lang.NoClassDefFoundError: scala/Product缺scala-library依赖pom里加scala-libraryUnsatisfiedLinkError: org.apache.hadoop.io.nativeio.NativeIO$Windowshadoop.dll没放System32复制hadoop.dll到C:\Windows\System32Unsupported class file major version 55JDK版本过高Java 11换回JDK 1.8Maven拉依赖卡住没配国内镜像settings.xml加阿里云镜像Error: A JNI error has occurredJDK版本混乱检查JAVA_HOME和IDEA项目SDK是否一致5.2 排查思路从下往上查遇到报错别慌按这个顺序查先看JDK版本对不对java -version再看Scala版本scala -version然后看Maven用的JDKmvn -v最后看IDEA项目里的Project SDK和Language Level。这四个地方版本一致了80%的问题就没了。IDEA里要检查三处File - Project Structure - Project里的SDK和Language LevelModules里的Scala SDKSettings - Build - Build Tools - Maven里的JDK for importer。5.3 几个我踩过的坑第一个坑IDEA里改了pom.xml但依赖没重新导入。改完pom一定要点右上角的Maven刷新按钮或者右键pom选Maven - Reload project。第二个坑local[*]在IDEA里跑没问题但打包成jar丢到集群上跑时忘了去掉setMaster结果集群模式被本地模式覆盖。正确做法是把setMaster从代码里去掉提交任务时用--master参数指定。第三个坑Windows下用sc.textFile(D:\\data\\input.txt)读文件路径里的反斜杠要转义或者直接用正斜杠D:/data/input.txtSpark两种都认。第四个坑中文乱码。Windows默认GBKSpark读文件默认UTF-8读中文文件会乱码。解决办法是文件本身存成UTF-8或者读的时候指定编码。6. 从本地模式到集群提交的过渡本地跑通只是第一步。真实项目里你需要把代码打包成jar提交到集群。用mvn clean package打包但要注意Spark相关依赖在集群上已经有了打包时应该用providedscope否则jar会巨大无比。dependency groupIdorg.apache.spark/groupId artifactIdspark-core_2.11/artifactId version${spark.version}/version scopeprovided/scope /dependency打包后提交命令大概长这样spark-submit \ --class com.demo.WordCount \ --master yarn \ --deploy-mode client \ spark-demo-1.0-SNAPSHOT.jar本地开发时用local[*]快速验证逻辑验证通过后去掉setMaster打包提交。这个流程走顺了你的Spark开发效率会提升一大截——不用每次改代码都重新打包上传本地就能调试大部分逻辑。我个人在实际操作中的体会是这套环境最难的不是装软件而是版本对齐和Windows特有的winutils配置。把这两个搞定剩下的就是写代码的事了。建议第一次搭建时把每个组件的版本号记在一个文档里以后换机器或者帮同事搭环境时直接照抄能省下大量试错时间。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑