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包有版本冲突了。