Spark學習(叄)- 環境搭建

Spark源碼編譯

1 寫在前面的話

有些小夥伴可能會問:Spark官網不是已經提供了Spark針對不同版本的安裝包了嗎,我們爲什麼還需要對Spark源碼進行編譯呢?針對這個問題我們到Spark官網: spark.apache.org來看下,如下圖所示:
在這裏插入圖片描述
Spark官網的確是提供了一些Hadoop版本的Spark安裝包,但是提供的這些是否能夠滿足我們的要求呢?答案肯定是否定的,根據本人近幾年做Spark的開發經驗,列出如下幾點

  • 在生產環境中Hadoop的選型,很大部分都是CDH或者HDP系列的,那麼官方提供的這幾個Hadoop系列是否能夠生產的需求?
  • 在開發過程中,我們經常會遇到需要對Spark的源碼進行修改,那麼修改後的代碼如何集成到Spark安裝包中去呢?

針對如上列出的兩點的個人覺得比較好的最佳實踐:

  • 根據生產上運行的Hadoop版本編譯出Spark的安裝包
  • 修改Spark源碼之後,重新編譯Spark

所以:個人覺得如果想更好的學習和使用Spark,那麼第一步就是要會根據Spark源碼編譯出安裝包。

2 前置準備

根據Spark官方文檔編譯模塊的介紹(http://spark.apache.org/docs/2.1.0/building-spark.html )的介紹:

The Maven-based build is the build of reference for Apache Spark. Building Spark using Maven requires Maven 3.3.9 or newer and Java 7+. Note that support for Java 7 is deprecated as of Spark 2.0.0 and may be removed in Spark 2.2.0.” 

我們得知:

  • Java需要7+版本,而且在Spark2.0.0之後Java 7已經被標識成deprecated了,但是不影響使用,但是在Spark2.2.0版本之後Java 7的支持將會被移除;
  • Maven需要3.3.9+版本

2.1 Java7的安裝

2.1.1 下載

Java SE安裝包下載地址:
https://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html
本文章我們使用的JDK版本是:jdk1.8.0_181

2.1.2 安裝

我們所有的軟件都安裝在hadoop用戶的根目錄的app文件夾下

//解壓
tar -zxvf jdk-XXX.tar.gz -C ~/app

//將JDK目錄添加到系統環境變量(~/.bash_profile)中
export JAVA_HOME=/home/hadoop/app/jdkjdk1.8.0_181
export PATH=$JAVA_HOME/bin:$PATH

//讓配置文件生效
source  ~/.bash_profile

//執行java,查看java版本
java -version 

//如果安裝成功後,則有如下信息的輸出
java version "jdk1.8.0_181"

2.2 Maven3.3.9的安裝

2.2.1 下載

Maven3.3.9安裝包下載地址:
https://mirrors.tuna.tsinghua.edu.cn/apache//maven/maven-3/3.3.9/binaries/

2.2.2安裝

// 解壓
tar -zxvf apache-maven-3.3.9-bin.tar.gz -C ~/app/

//將JDK目錄添加到系統環境變量(~/.bash_profile)中
export MAVEN_HOME=/home/hadoop/app/apache-maven-3.3.9
export PATH=$MAVEN_HOME/bin:$PATH

//讓配置文件生效
source  ~/.bash_profile

//執行mvn,查看版本
mvn -v

//如果安裝成功後,則有如下信息的輸出
Apache Maven 3.3.9 (bb52d8502b132ec0a5a3f4c09453c07478323dc5; 2015-11-10T08:41:47-08:00)
Maven home: /home/hadoop/app/apache-maven-3.3.9
Java version: 1.7.0_51, vendor: Oracle Corporation
Java home: /home/hadoop/app/jdk1.7.0_51/jre
Default locale: zh_CN, platform encoding: UTF-8
OS name: "linux", version: "2.6.32-358.el6.x86_64", arch: "amd64", family: "unix"

2.3 Spark-2.1.0源碼下載

下載地址:http://spark.apache.org/downloads.html
在這裏插入圖片描述
下載完成後解壓即可,解壓後的目錄結構如下圖所示
在這裏插入圖片描述

3 Spark源碼編譯

查看官方文檔編譯源碼部分:http://spark.apache.org/docs/2.1.0/building-spark.html#building-a-runnable-distribution

我們可以使用Spark源碼目錄中的dev下的make-distribution.sh腳本,官方提供的編譯命令如下:

./dev/make-distribution.sh --name custom-spark --tgz -Psparkr -Phadoop-2.4 -Phive -Phive-thriftserver -Pmesos -Pyarn

參數說明:

  • –name:指定編譯完成後Spark安裝包的名字
  • –tgz:以tgz的方式進行壓縮
  • -Psparkr:編譯出來的Spark支持R語言
  • -Phadoop-2.4:以hadoop-2.4的profile進行編譯,具體的profile可以看出源碼根目錄中的pom.xml中查看
  • -Phive和-Phive-thriftserver:編譯出來的Spark支持對Hive的操作
  • -Pmesos:編譯出來的Spark支持運行在Mesos上
  • -Pyarn:編譯出來的Spark支持運行在YARN上

那麼我們可以根據具體的條件來編譯Spark,比如我們使用的Hadoop版本是2.6.0-cdh5.7.0,並且我們需要將Spark運行在YARN上、支持對Hive的操作,那麼我們的Spark源碼編譯腳本就是:

./dev/make-distribution.sh --name 2.6.0-cdh5.7.0 --tgz  -Pyarn -Phadoop-2.6 -Phive -Phive-thriftserver -Dhadoop.version=2.6.0-cdh5.7.0

編譯成功後,在Spark源碼的根目錄中就spark-2.1.0-bin-2.6.0-cdh5.7.0.tgz包,那麼我們就可以使用編譯出來的這個安裝包來進行Spark的安裝了。

有小夥伴可能會問,爲什麼編譯出來的安裝包的名稱是spark-2.1.0-bin-2.6.0-cdh5.7.0.tgz呢?我們可以帶着這個疑惑,查看make-distribution.sh的源碼,在該腳本的最後部分,有如下代碼:

if [ "$MAKE_TGZ" == "true" ]; then
  TARDIR_NAME=spark-$VERSION-bin-$NAME
  TARDIR="$SPARK_HOME/$TARDIR_NAME"
  rm -rf "$TARDIR"
  cp -r "$DISTDIR" "$TARDIR"
  tar czf "spark-$VERSION-bin-$NAME.tgz" -C "$SPARK_HOME" "$TARDIR_NAME"
  rm -rf "$TARDIR"
fi

該VERSION就是我們Spark的版本即2.1.0,NAME就是我們在編譯時指定的2.6.0-cdh5.7.0,所以根據該腳本最終輸出的Spark安裝包的全稱爲: spark-2.1.0-bin-2.6.0-cdh5.7.0.tgz。通過該代碼的查看希望大家能明白一個問題:源碼面前,了無祕密。

注意:在編譯過程中會出現下載某個依賴包的時間太久,這是由於網絡問題,可以執行ctrl+c停止編譯命令,然後重新運行編譯命令,在編譯過程中多試幾次即可。有條件的小夥伴,建議開着VPN然後再進行編譯,整個編譯過程會順暢很多。

編譯好的spark-2.1.0-bin-2.6.0-cdh5.7.0版本鏈接爲:
https://download.csdn.net/download/bingdianone/10824595

以上文章來自:
鏈接:https://www.imooc.com/article/18419

Spark環境編譯中的問題:

編譯命令

./dev/make-distribution.sh \
--name 2.6.0-cdh5.7.0  \
--tgz  \
-Pyarn -Phadoop-2.6 \
-Phive -Phive-thriftserver \
-Dhadoop.version=2.6.0-cdh5.7.0

如果在編譯過程中,你看到的異常信息不是太明顯/看不太懂
編譯命令後 -X ,就能看到更詳細的編譯信息

問題一

Failed to execute goal on project spark-launcher_2.11: 
Could not resolve dependencies for project org.apache.spark:spark-launcher_2.11:jar:2.1.0: 
Could not find artifact org.apache.hadoop:hadoop-client:jar:2.6.0-cdh5.7.0 
in central (https://repo1.maven.org/maven2) -> [Help 1]

問題一解決:pom.xml添加:

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

問題二

export MAVEN_OPTS="-Xmx2g -XX:ReservedCodeCacheSize=512m -XX:MaxPermSize=512M"

注意點:
有些是阿里雲的機器,但是你這機器的內存可能有限的,建議你們vm至少2-4G
VM:設置8G

[info] Java HotSpot(TM) 64-Bit Server VM warning: INFO: os::commit_memory(0x00000000e8f84000, 18800640, 0) failed; error='無法分配內存' (errno=12)
[info] #
[info] # There is insufficient memory for the Java Runtime Environment to continue.
[info] # Native memory allocation (malloc) failed to allocate 18800640 bytes for committing reserved memory.
[info] # An error report file with more information is saved as:
[info] # /home/hadoop/source/spark-2.1.0/hs_err_pid4764.log

問題三

如果編譯的是scala版本是2.10
需要加上
./dev/change-scala-version.sh 2.10

./dev/change-scala-version.sh 2.11

問題四

was cached in the local repository, 
resolution will not be reattempted until the update interval of nexus has elapsed or updates are forced  

1) 去倉庫把 xxx.lastUpdated文件全部刪除,重新執行maven命令
2) 編譯命令後面 -U

Spark環境搭建-待補充

Spark Local模式環境搭建

直接解壓spark-2.1.0-bin-2.6.0-cdh5.7.0.tgz
配置好環境變量 可以直接使用。

Spark Standalone模式環境搭建

Spark Standalone模式的架構和Hadoop HDFS/YARN很類似的
1 master + n worker

修改 /spark-env.sh
SPARK_MASTER_HOST=hadoop001
SPARK_WORKER_CORES=2 每個worker啓動幾個core
SPARK_WORKER_MEMORY=2g 分配給每個worker的內存
SPARK_WORKER_INSTANCES=1 每個worker啓動幾個實例(幾個worker)

hadoop1 : master
hadoop2 : worker
hadoop3 : worker
hadoop4 : worker

hadoop10 : worker

slaves:
hadoop2
hadoop3
hadoop4

hadoop10

==> start-all.sh 會在 hadoop1機器上啓動master進程,在slaves文件配置的所有hostname的機器上啓動worker進程

Spark WordCount統計

val file = spark.sparkContext.textFile("file:///home/hadoop/data/wc.txt")
val wordCounts = file.flatMap(line => line.split(",")).map((word => (word, 1))).reduceByKey(_ + _)
wordCounts.collect
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章