spark源码编译

  1. 获取spark源码

    • 从github上clone spark项目:git clone https://github.com/apache/spark.git
    • 将代码导入到Idea中
    • checkout指定版本的spark代码(3.0.0为例):git checkout -b v3.0.0 v3.0.0
  2. mvn打包

    • 指定mvn坏境配置:export MAVEN_OPTS="-Xmx2g -XX:MaxPermSize=512M -XX:ReservedCodeCacheSize=512m"
    • 指定需要的profile进行打包:mvn clean package -Phadoop-2.7 -Dhadoop.version=2.7.4 -Phive -Phive-thriftserver -Pyarn -DskipTests

      注意:由于编译过程Maven需要下载依赖,编译的所在机器必须可以访问网络,甚至需要翻墙才可以编译成功,所以第一次编译可能很慢。
      使用 mvn 之前需要安装 maven,这里不再赘述,当然也可以使用 Spark 源码自带 maven 可以不安装

如果出现下面错误:
spark源码编译打包 - 图1
enforcer是做环境约束检查用,到pom.xml中找到对应的enforce插件:

  1. <plugin>
  2. <groupId>org.apache.maven.plugins</groupId>
  3. <artifactId>maven-enforcer-plugin</artifactId>
  4. <version>3.0.0-M2</version>
  5. <executions>
  6. <execution>
  7. <id>enforce-versions</id>
  8. <goals>
  9. <goal>enforce</goal>
  10. </goals>
  11. <configuration>
  12. <rules>
  13. <requireMavenVersion>
  14. <version>${maven.version}</version>
  15. </requireMavenVersion>
  16. <requireJavaVersion>
  17. <version>${java.version}</version>
  18. </requireJavaVersion>
  19. <bannedDependencies>
  20. <excludes>
  21. <exclude>org.jboss.netty</exclude>
  22. <exclude>org.codehaus.groovy</exclude>
  23. <exclude>*:*_2.11</exclude>
  24. <exclude>*:*_2.10</exclude>
  25. </excludes>
  26. <searchTransitive>true</searchTransitive>
  27. </bannedDependencies>
  28. </rules>
  29. </configuration>
  30. </execution>
  31. <execution>
  32. <id>enforce-no-duplicate-dependencies</id>
  33. <goals>
  34. <goal>enforce</goal>
  35. </goals>
  36. <configuration>
  37. <rules>
  38. <banDuplicatePomDependencyVersions/>
  39. </rules>
  40. </configuration>
  41. </execution>
  42. </executions>
  43. </plugin>

这里对java.version和maven.version做了约束,把配置改成本地对应的版本号即可。

指定maven version:(我本地maven版本是3.5.4)
mvn clean package -Dmaven.version=3.5.4 -Phadoop-2.7 -Dhadoop.version=2.7.4 -Phive -Phive-thriftserver -Pyarn -DskipTests

经过漫长的等待,见到如下图说明编译成功:
spark源码编译打包 - 图2

编译生成 tgz 包

在 spark 源码目录执行 make-distribution 编译命令:

  1. ./dev/make-distribution.sh \
  2. --name cdh2.6 \
  3. --tgz \
  4. -Pyarn -Phadoop-2.6 -Phive -Phive-thriftserver \
  5. -Dhadoop.version=2.6.0-cdh5.13.1 \
  6. -Dmaven.version=3.5.4 \
  7. -Dscala.version=2.11.12 \
  8. -Dscala.binary.version=2.11 \
  9. -Djava.version=1.14 \
  10. -DskipTests

参数说明:
—name: 表示打包的名称,最终生成为 spark-${spark-version}-bin-cdh2.6.tgz
—tgz: 打包成 tgz 格式
-Dhadoop.version: 指定hadoop版本为2.6.0-cdh5.13.1
-DskipTests: 不执行测试用例,但编译测试用例类生成相应的class文件至target/test-classes下
对于maven/scala/java version根据实际情况指定

执行如果出现下面错误:
spark源码编译打包 - 图3
说明是在使用build/mvn命令时发生了异常。我们单独执行build/mvn,发现下面错:
spark源码编译打包 - 图4
说明是curl访问https地址出现SSL证书错误,原来是找不到本地的证书。我们通过错误提示里面的证书下载地址:https://curl.haxx.se/docs/sslcerts.html 找到证书下载地址。下载完成后指定env:export CURL_CA_BUNDLE=/spark/cacert.pem就可以解决了。

如果你指定hadoop为cdh版本,jar包down不下来:
spark源码编译打包 - 图5
解决方法:在主pom.xml添加cdh版的maven仓库:

<repository>
  <id>cloudera</id>
  <url>https://repository.cloudera.com/artifactory/cloudera-repos/</url>
</repository>

填坑

整合hive异常

错误信息大概是这样:hive.ql.metadata.HiveException: Unable to fetch table Invalid method name: get_table_req
原因是spark3源码默认使用2.3.7版本的hive,里面的getTable方法调用了get_table_req,而hive客户端的版本<=1.2.x找不到get_table_req的方法,所以报了Invalid method name:get_table_req
解决方法:指定hive的版本为1.2.1,打包的时候指定-Phive-1.2

hdfs Kerberos token过期问题

错误信息大概是这样:spark hadoop.security.token.SecretManager token can't be found in cache
原因是打包使用hadoop-2.7官方是没有解决这方面问题的(线上也是使用cdh的hadoop)
解决方法:打包指定cdh版本的hadoop依赖,指定-Dhadoop.version=2.6.0-cdh5.13.1

hdfs native snappy library not available问题

错误信息大概是这样:native snappy library not available: this version of libhadoop was built without snappy support.
解决方法:指定JAVA_LIBRARY_PATH为native so文件路径

export JAVA_LIBRARY_PATH=$JAVA_LIBRARY_PATH:\
/opt/cloudera/parcels/CDH/lib/hadoop/lib/native

export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:\
/opt/cloudera/parcels/GPLEXTRAS/lib/hadoop/lib/native:\
/opt/cloudera/parcels/CDH/lib/hadoop/lib/native

export SPARK_DIST_CLASSPATH=/etc/hadoop/conf:\
/opt/cloudera/parcels/CDH/lib/hadoop/lib/*:\
/opt/cloudera/parcels/CDH/lib/hadoop/lib/native/*:\
/opt/cloudera/parcels/GPLEXTRAS/lib/hadoop/lib/*::

executor端:启动脚本添加java.library.path为native so文件路径

ENV SPARK_EXECUTOR_NATIVE_JAVA_OPTS="-Djava.library.path=/opt/cloudera/parcels/CDH/lib/hadoop/lib/native/"

executor)
    shift 1
    CMD=(
      ${JAVA_HOME}/bin/java
      "${SPARK_EXECUTOR_NATIVE_JAVA_OPTS[@]}"
      "${SPARK_EXECUTOR_JAVA_OPTS[@]}"
      -Xms$SPARK_EXECUTOR_MEMORY
      -Xmx$SPARK_EXECUTOR_MEMORY
      -cp "$SPARK_CLASSPATH:$SPARK_DIST_CLASSPATH"
      org.apache.spark.executor.CoarseGrainedExecutorBackend
      --driver-url $SPARK_DRIVER_URL
      --executor-id $SPARK_EXECUTOR_ID
      --cores $SPARK_EXECUTOR_CORES
      --app-id $SPARK_APPLICATION_ID
      --hostname $SPARK_EXECUTOR_POD_IP
    )
    ;;

Spark3和hadoop兼容问题

Spark 3.0 官方默认支持的Hadoop最低版本为2.7, Hive最低版本为 1.2。我们平台使用的CDH 5.13,对应的版本分别为hadoop-2.6.0, hive-1.1.0。所以在编译yarn模块会报错:
具体是/resource-managers/yarn/src/main/scala/org/apache/spark/deploy/yarn/Client.scala的
298行logAggregationContext.setRolledLogsIncludePattern(includePattern)
300行logAggregationContext.setRolledLogsExcludePattern(excludePattern)问题
由于这两个方法是hadoop2.6.4添加的,如果你的hadoop版本低于2.6.4,那么编译就会报错。
解决方法:参考https://github.com/apache/spark/pull/16884/files

https访问异常

错误信息大概是这样:PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException
原因是:访问https服务需要指定证书
解决方法:
将安全证书安装后, 添加至本地Jre security中,

cd /Library/Java/JavaVirtualMachines/jdk1.8.0_131.jdk/Contents/Home/jre/lib/security 目录下执行:

keytool -import  -v -alias DXYcacerts -keystore
"/Library/Java/JavaVirtualMachines/jdk1.8.0_131.jdk/Contents/Home/jre/lib/security/cacerts"
-file "/xxx/xxxx/DXYcacerts.cer"

./dev/make-distribution.sh
—name hadoop2.7
—tgz
-Pyarn -Phadoop-2.7 -Phive-1.2 -Phive-thriftserver -Pkubernetes
-DskipTests

./dev/make-distribution.sh
—name cdh2.6-with-k8s
—tgz
-Dhadoop.version=2.6.0-cdh5.13.1
-Phadoop-2.6 -Phive-1.2 -Phive-thriftserver -Pkubernetes
-DskipTests

./dev/make-distribution.sh
—name cdh2.6-without-k8s
—tgz
-Dhadoop.version=2.6.0-cdh5.13.1
-Pyarn -Phadoop-2.6 -Phive-1.2 -Phive-thriftserver
-DskipTests

./dev/make-distribution.sh
—name cdh2.6-with-k8s
—tgz
-Dhadoop.version=2.6.0-cdh5.13.1
-Pyarn -Phadoop-2.6 -Phive-1.2 -Phive-thriftserver -Pkubernetes
-DskipTests