Idea+Maven+Git搭建Spark源码阅读环境

Posted on Wed, Sep 11, 2019 Spark Idea Maven

1. 环境准备

下面是我搭建环境时本地各组件的版本:

在开始编译 Spark 之前,最好先在 Maven 配置好国内镜像源,绝大部分问题都是由于仓库配置导致的。在 Meven 路径下 settings.xml 的 <mirrors/> 标签里添加如下内容:

		<mirror>
      <id>aliyun central</id>
      <mirrorOf>central</mirrorOf>
      <name>阿里云中央仓库</name>
      <url>https://maven.aliyun.com/repository/central</url>
    </mirror>

     <mirror>
      <id>aliyun apache snapshotsl</id>
      <mirrorOf>apache.snapshots</mirrorOf>
      <name>阿里云 apache snapshots 仓库</name>
      <url>https://maven.aliyun.com/repository/apache-snapshots</url>
    </mirror>

     <mirror>
      <id>aliyunmaven</id>
      <mirrorOf>public</mirrorOf>
      <name>阿里云public仓库</name>
      <url>https://maven.aliyun.com/repository/public</url>
    </mirror>

2. Git拉取Spark项目

首先使用Git拉取官方 Spark 项目,github 项目地址:https://github.com/apache/spark

由于Spark项目很大,再加上服务器位于国外,所以拉取项目的过程会十分的慢,可能需要几个小时,这里提供一个节省时间的取巧方法:

3. Idea导入Spark项目

此处编译 Spark2.1.0 版本,首先将 Spark 顶层目录下 pom.xml 文件的 java 版本从 1.7 修改为 1.8。

 <!-- <java.version>1.7</java.version> -->
 <java.version>1.8</java.version>
  1. 启动Idea,点击 File -> Import Project;
  2. 选择 Spark 顶级目录下的 pom 文件,项目类型为 Maven Project,推荐勾选 Import Maven projects automatically;
  3. 修改 Environment settings,修改 Maven 及其配置文件为本地的 Maven 配置,导入后 Idea 会自动编译,需要等待一段时间。

4. Idea编译过程遇到的一些问题

Ctrl+Shift+N 打开 LocalPi.scala 并运行,接下来会出现很多问题,我们一个一个解决。

4.1 Error:(xx, xx) not found: type xxx

 Error:(45, 66) not found: type SparkFlumeProtocol
   val transactionTimeout: Int, val backOffInterval: Int) extends SparkFlumeProtocol with Logging {

解决方法:点击 Idea 右侧的 Maven Projects(如果找不到该窗口,则点击 Idea 上方导航 Help->Find Action(Ctrl+Shift+A) ,输入 Maven projects),找到 Spark Project External Flume Sink,右键点击 Generate Sources and Update Folders 即可,需要等待较长的一段时间(取决于电脑配置)。

接下来还会遇到多次这类错误,如果不想一个一个点也可以点击 Maven Project 窗口上方的 Generate Sources and Update Folders For All Projects,但不一定生效,取决于 maven 版本,较新版本的 maven 不会出现该问题,官方文档有解释说明:

The version of Maven bundled with IntelliJ may not be new enough for Spark. If that happens, the action “Generate Sources and Update Folders For All Projects” could fail silently. Please remember to reset the Maven home directory (Preference -> Build, Execution, Deployment -> Maven -> Maven home directory) of your project to point to a newer installation of Maven. You may also build Spark with the script build/mvn first. If the script cannot locate a new enough Maven installation, it will download and install a recent version of Maven to folder build/apache-maven-<version>/.

4.2 java.lang.NoClassDefFoundError: scala/Function1

再次运行 LocalPi.scala,这次会出现以下错误:

 Exception in thread "main" java.lang.NoClassDefFoundError: scala/Function1
     at org.apache.spark.examples.LocalPi.main(LocalPi.scala)
 Caused by: java.lang.ClassNotFoundException: scala.Function1
     at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
     at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
     at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:349)
     at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
     ... 1 more

此处为Scala的sdk配置问题,选中sprak项目,Ctrl+Alt+Shift+S 打开项目对应的 Project Structure,点击 Global Libraries,如果看到已经配置了 scala-sdk,则将其删除,重新添加,并选择 module 生效范围,此处选择全部 module。

再次运行,成功输出如下信息则代表配置生效:

 Pi is roughly 3.15404
 ​
 Process finished with exit code 0

4.3 java.lang.NoClassDefFoundError: org/apache/spark/sql/SparkSession$

成功运行 LocalPi.scala 后,开始运行 SparkPi.scala,首次运行会出现以下错误:

 Exception in thread "main" java.lang.NoClassDefFoundError: org/apache/spark/sql/SparkSession$
     at org.apache.spark.examples.SparkPi$.main(SparkPi.scala:28)
     at org.apache.spark.examples.SparkPi.main(SparkPi.scala)
 Caused by: java.lang.ClassNotFoundException: org.apache.spark.sql.SparkSession$
     at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
     at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
     at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:349)
     at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
     ... 2 more

由于 SparkPi.scala 是属于 spark-examples 模块的的,需要依赖 spark-sql 模块运行,而在 spark-examples 的 pom 文件中对 spark-sql 的 scope 配置为 provided,因此需要对 spark-example 的默认 run Configuration 进行修改。 选中 Idea 上的 Run->Edit Configurations->Templates->ApplicationUse classpath of module 选择为 spark-examples,勾选 Include dependencies with "Provided" scope,并编辑 VM optiopns,添加-Dspark.master=local[2]参数,如图所示:

4.4 org.apache.spark.SparkException: Error while locating file spark-version-info.properties

再次运行 SparkPi.scala ,抛出该错误,是因为 spark-core 模块缺少了 spark-version-info.properties 文件,这个文件需要我们去手动生成(具体原因不明,估计 maven 编译起来的效果还是不如 sbt 好,然而 sbt 国内网络环境又差)。

接下来去到 Spark 的目录下,启动git bash,指定以下命令生成该文件:

 # 2.1.0为对应Spark版本
 build/spark-build-info core/target/extra-resources 2.1.0

然后 Idea 中选中 spark-core 模块,选择 Idea 菜单上的 Build->Rebuild Module spark-core 重新进行构建,再次运行 SparkPi.scala,可以看到控制台开始输出Spark相关日志,大功告成!

 ...
 19/09/05 15:20:32 INFO TaskSetManager: Finished task 0.0 in stage 0.0 (TID 0) in 146 ms on localhost (executor driver) (1/2)
 19/09/05 15:20:32 INFO TaskSetManager: Finished task 1.0 in stage 0.0 (TID 1) in 111 ms on localhost (executor driver) (2/2)
 19/09/05 15:20:32 INFO TaskSchedulerImpl: Removed TaskSet 0.0, whose tasks have all completed, from pool 
 19/09/05 15:20:32 INFO DAGScheduler: ResultStage 0 (reduce at SparkPi.scala:38) finished in 0.174 s
 19/09/05 15:20:32 INFO DAGScheduler: Job 0 finished: reduce at SparkPi.scala:38, took 0.426254 s
 Pi is roughly 3.1396556982784913
 19/09/05 15:20:32 INFO ServerConnector: Stopped Spark@401f7633{HTTP/1.1}{0.0.0.0:4041}
 ...

以上就是本次的搭建过程,如果有什么问题,欢迎指出交流。