arm64 上编译 spark-2.4.5-bin-hadoop2.7
背景
在aarch64机器上编译spark并制作spark-2.4.5-bin-hadoop2.7.tgz 文件
编译环境
宿主机arch: aarch64
Docker FROM: adoptopenjdk/openjdk8:debian
spark: 2.4.5
JAVA: 系统自动安装
maven: 系统自动安装
scala: 2.12.13
编译过程
使用maven编译,首先下载spark源码包和依赖安装
wget https://github.com/apache/spark/archive/v2.4.5.tar.gz && tar -xzf v2.4.5.tar.gz apt-get purge openjdk* && \ apt-get -y install software-properties-common maven build-essential autoconf automake libtool cmake zlib1g-dev pkg-config libssl-dev libprotobuf-dev protobuf-compiler libsnappy-dev bzip2 libbz2-dev libjansson-dev fuse libfuse-dev apt-utils
cd spark-2.4.5
官方推荐的是使用 ./build/mvn 进行安装,但是其中依赖的zinc项目在实际使用过程中会抛出以下错误
/spark-2.4.5/build/zinc-0.3.15/bin/ng/linux32/ng: cannot execute binary file: Exec format error
其中linux32可以看到明显错误,我们使用的是linux64的机器,在一篇文章中看到错误的产生如下:
# zinc-0.3.15/bin/nailgun if ! ng_exists ; then # choose bundled binary based on platform declare -r una=$( uname -a | tr "[:upper:]" "[:lower:]" ) declare platform="" case "$una" in *cygwin*) platform="win32" ;; *mingw32*) platform="win32" ;; *darwin*x86_64*) platform="darwin64" ;; *darwin*) platform="darwin32" ;; *linux*x86_64*) platform="linux64" ;; *linux*ppc64le*) platform="linuxppc64le" ;; *linux*) platform="linux32" ;; *) platform="unknown" ;; esac cmd="$script_dir/ng/$platform/ng" [[ -x "$cmd" ]] && ng_cmd="$cmd" fi
通过uanme -r命令可以看到zinc错误的匹配了linux*的选项,导致platform=linux32。对于该问题的解决是
1. 通过./build/mvn 文件中注视掉zinc的选项
2. 直接使用命令 mvn 进行编译,本文中使用这种方法。
同时zinc在后台启动了一个进程,需要kill. ps -ef | grep zinc
尝试使用默认构建的方式
mvn -DskipTests clean package
下载的过程很慢,并且遇到如下错误
'parent.relativePath' points at wrong local POM
根据提示和pom.xml的语法得知,缺少parent标签表示的父级目录的pom.xml文件,手动下载该pom.xml 文件
pom.xml文件定义的parent
wget -P ../ https://maven-central.storage-download.googleapis.com/repos/central/data/org/apache/apache/18/apache-18.pom
再次执行 mvn -DskipTests clean package
编译的过程非常慢,尝试使用国内的maven镜像加速,更改maven的配置文件
vim /etc/maven/settings.xml ,添加以下内容
<mirrors> <mirror> <id>mirror</id> <mirrorOf>!rdc-releases,!rdc-snapshots</mirrorOf> <name>mirror</name> <url>https://maven.aliyun.com/nexus/content/groups/public</url> </mirror> </mirrors>
再次执行 mvn -DskipTests clean package,遇到以下错误
Connect to maven.aliyun.com:443[maven.aliyun.com] failed: Connection timed out: connect
该问题导致我一度卡住,后来发现是maven在外网环境下不需要设置代理,在内网需要在xml文件中指定proxy
<proxies>
<proxy>
<id>optional</id>
<active>true</active>
<protocol>http</protocol>
<username>proxyuser</username>
<password>proxypass</password>
<host>ip</host>
<port>port</port>
<nonProxyHosts>local.net|some.host.com</nonProxyHosts>
</proxy>
</proxies>
再次执行 mvn -DskipTests clean package,编译成功。说明spark在arm64平台上是可编译的。
接下来就可以打我们需要的包了,首先需要做些配置
sed -i '/\<useZincServer\>/d' pom.xml #关闭zinc的使用
sed -i '/\<hadoop\.version\>/s@2.6.5@2.7@' pom.xml # 指定hadoop的版本
export MAVEN_OPTS="-Xms1024m -Xmx12G -XX:PermSize=4096m" # 根据机器的配置设置,也可以使用默认的
执行打包命令
./dev/make-distribution.sh --tgz -Pyarn -Phive -Phive-thriftserver -Psparkr -Phadoop-2.7 -Dhadoop.version=2.7 -DrecompileMode=all -DskipTests
执行过程中会遇到 tail 命令卡住的情况,通过查看make-distribution.sh发现tail命令用于获取版本信息,我们手动替换即可
sed -i '128,146d' ./dev/make-distribution.sh
sed -i '128s/^/VERSION=2.4.5\nSCALA_VERSION=2.12.13\nSPARK_HADOOP_VERSION=2.7\nSPARK_HIVE=1.2.1.spark2\n/' ./dev/make-distribution.sh
root@09b7f244236e:/spark-2.4.5# vim ./dev/make-distribution.sh
再次执行 ./dev/make-distribution.sh --tgz -Pyarn -Phive -Phive-thriftserver -Psparkr -Phadoop-2.7 -Dhadoop.version=2.7 -DrecompileMode=all -DskipTests
执行成功,目录下新增 spark-2.4.5-bin-hadoop2.7.tgz 文件。
如果scala编译错误,版本可替换为2.11
参考文章
https://bbs.huaweicloud.com/forum/thread-63989-1-1.html
https://kiwik.github.io/arm/2019/06/04/%E5%9C%A8-ARM64-%E4%B8%8A%E7%BC%96%E8%AF%91%E6%B5%8B%E8%AF%95-Spark