利用Spark2.2.0源码编译生成适合于CDH5.14.4的Spark包

本文详细介绍如何自定义编译Spark以解决版本兼容性问题,包括编译前的准备、修改配置、选择编译方法及参数,以及如何避免与Hadoop、Yarn的版本冲突。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1. 不使用预编译版本安装包的原因:

因为开源版本的组件如Hadoop、HBase、flume等等配合使用时可能会有jar包的冲突,所以下载相应的CDH版本进行安装。
因为Spark的预编译版本如 spark-2.2.0-bin-hadoop2.6.tgz spark-2.2.0-bin-hadoop2.7.tgz,可能存在小版本的兼容问题。所以下载Spark2.2的源码,然后进行编译安装。

2. 编译方法:

注意:
不要使用scala2.11.12进行编译打包,否则在编译过程中会报出以下错误,最好使用scala2.11.8进行编译打包
[ERROR] Failed to execute goal net.alchim31.maven:scala-maven-plugin:3.2.2:compile (scala-compile-first) on project spark-repl_2.11: Execution scala-compile-first of goal net.alchim31.maven:scala-maven-plugin:3.2.2:compile failed.: CompileFailed -> [Help 1]
org.apache.maven.lifecycle.LifecycleExecutionException: Failed to execute goal net.alchim31.maven:scala-maven-plugin:3.2.2:compile (scala-compile-first) on project spark-repl_2.11: Execution scala-compile-first of goal net.alchim31.maven:scala-maven-plugin:3.2.2:compile failed.

官网上提供了两种编译方法:
Maven命令直接编译 和 使用 dev/make-distribution.sh 进行编译

编译前要修改的地方

1)在源码根路径下的 pom.xml 中添加,这样可以从Cloudera和阿里云加载依赖包,能加快下载速度且尽量避免被墙

    <repository>
      <id>nexus-aliyun</id>
      <name>Nexus aliyun</name>
      <url>http://maven.aliyun.com/nexus/content/groups/public</url>
    </repository>
    <repository>
      <id>cloudera</id>  <!-- Cloudera Repository -->
      <name>Cloudera Repository</name>
      <url>https://repository.cloudera.com/artifactory/cloudera-repos</url>
    </repository>

2)修改 ./build/mvn 中 install_scala()的代码,可以指定SCALA_COMPILER和SCALA_LIBRARY的路径而禁止在编译过程中下载scala语言包

install_scala() {
  # determine the Scala version used in Spark
  local scala_version=`grep "scala.version" "${_DIR}/../pom.xml" | head -n1 | awk -F '[<>]' '{print $3}'`
  local scala_bin="${_DIR}/scala-${scala_version}/bin/scala"
  local TYPESAFE_MIRROR=${TYPESAFE_MIRROR:-https://downloads.typesafe.com}

  #install_app \
  #  "${TYPESAFE_MIRROR}/scala/${scala_version}" \
  #  "scala-\${scala_version}.tgz" \
  #  "scala-\${scala_version}/bin/scala"

  #SCALA_COMPILER="$(cd "$(dirname "${scala_bin}")/../lib" && pwd)/scala-compiler.jar"
  #SCALA_LIBRARY="$(cd "$(dirname "${scala_bin}")/../lib" && pwd)/scala-library.jar"
  SCALA_COMPILER="${SCALA_HOME}/lib/scala-compiler.jar"
  SCALA_LIBRARY="${SCALA_HOME}/lib/scala-library.jar"
}

如果已经下载过ZINC了,再重新编译打包的话可以注释掉下载和安装ZINC的代码以加快重新打包的时间。

install_zinc() {
  local zinc_path="zinc-0.3.11/bin/zinc"
  #[ ! -f "${_DIR}/${zinc_path}" ] && ZINC_INSTALL_FLAG=1
  #local TYPESAFE_MIRROR=${TYPESAFE_MIRROR:-https://downloads.typesafe.com}

  #install_app \
  #  "${TYPESAFE_MIRROR}/zinc/0.3.11" \
  #  "zinc-0.3.11.tgz" \
  #  "${zinc_path}"
  ZINC_BIN="${_DIR}/${zinc_path}"
}

3)因已经装了高于3.3.9的Maven版本,所以会使用已安装的maven
4)如果明确了版本,可以替换 dev/make-distribution.sh 的以下内容以加快编译速度

VERSION=2.2.0
SCALA_VERSION=2.11.8
SPARK_HADOOP_VERSION=2.6.0-cdh5.14.4
SPARK_HIVE=1
#VERSION=$("$MVN" help:evaluate -Dexpression=project.version $@ 2>/dev/null | grep -v "INFO" | tail -n 1)
#SCALA_VERSION=$("$MVN" help:evaluate -Dexpression=scala.binary.version $@ 2>/dev/null\
#   | grep -v "INFO"\
#   | tail -n 1)
#SPARK_HADOOP_VERSION=$("$MVN" help:evaluate -Dexpression=hadoop.version $@ 2>/dev/null\
#    | grep -v "INFO"\
#    | tail -n 1)
#SPARK_HIVE=$("$MVN" help:evaluate -Dexpression=project.activeProfiles -pl sql/hive $@ 2>/dev/null\
#    | grep -v "INFO"\
#    | fgrep --count "<id>hive</id>";\
#    # Reset exit status to 0, otherwise the script stops here if the last grep finds nothing\
#    # because we use "set -o pipefail"
#    echo -n)
Maven命令直接编译

进入源码目录,运行以下命令

export MAVEN_OPTS="-Xmx2g -XX:ReservedCodeCacheSize=512m"
mvn -Pyarn -Phadoop-2.6 -Phive -Phive-thriftserver \
-Dhadoop.version=2.6.0-cdh5.14.4 \
-Pflume -Dflume.version=1.6.0-cdh5.14.4 \
-Dscala.version=2.11.8 -DskipTests \
clean package

编译生成的jar包位于 assembly/target/scala-2.11/jars 路径下。
这种方式编译后,不能形成可以发布的安装包,下一种方式就可以。

使用 dev/make-distribution.sh 进行编译

如果需要编译一个可以执行的tgz包的话,可以直接运行以下命令(推荐使用)

./dev/make-distribution.sh --name 2.6.0-cdh5.14.4 \
--pip --r --tgz -Psparkr -Pyarn -Phadoop-2.6 -Phive -Phive-thriftserver \
-Dhadoop.version=2.6.0-cdh5.14.4 -Dflume.version=1.6.0-cdh5.14.4 \
-Dzookeeper.version=3.4.5-cdh5.14.4 -Dscala.version=2.11.8

如果不需要 pyspark 和 sparkr,则去掉 --r -Psparkr和 --pip

./dev/make-distribution.sh --name 2.6.0-cdh5.14.4 \
--tgz -Pyarn -Phadoop-2.6 -Phive -Phive-thriftserver \
-Dhadoop.version=2.6.0-cdh5.14.4 -Dflume.version=1.6.0-cdh5.14.4 \
-Dzookeeper.version=3.4.5-cdh5.14.4 -Dscala.version=2.11.8

编译生成的jar包位于 Spark源码根 路径下,文件名为spark-2.2.0-bin-2.6.0-cdh5.14.4.tgz。

编译时选择Profile以及相应组件的版本

查看源码根路径下的pom.xml:
选择相应的profile,可以编译打包出相应的 jar包
查看相关组件的version,如 <hadoop.version>,如果存在就可以在参数中通过 -Dhadoop.version 进行指定。

给Yarn配置 Spark jar文件

为了Yarn可以正常运行Spark程序,可以在spark-default.conf中配置 spark.yarn.jars 指向一个hdfs路径,把$SPARK_HOME/jars/*.jars 上传到这个hdfs路径上,这样Yarn可以读取执行Spark程序所需的spark的相关Jar文件。
但是如果这些Spark的相关jar中含有Yarn、Hadoop的相关jar,就可能会和当前Hadoop环境的jar的版本不同,而导致冲突。
使用 -Phadoop-provided 参数进行编译,可以在Spark源码被编译打包时不生成和Hadoop、Yarn相关jar包,把其他的jar上传至 spark.yarn.jars 指向的hdfs路径,就可以在提交Spark作业到Yarn上执行时避免与Hadoop Yarn上的jar包有版本冲突了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值