一 下載下傳安裝包
1 官方下載下傳
官方下載下傳位址:http://spark.apache.org/downloads.html

2 安裝前提
- Java8 安裝成功
- zookeeper 安裝參考:CentOS7.5搭建Zookeeper3.4.12叢集
- hadoop 安裝參考:CentOS7.5搭建Hadoop2.7.6叢集
- Scala 安裝成功
注意:從Spark2.0版開始,預設使用Scala 2.11建構。Scala 2.10使用者應該下載下傳Spark源包并使用Scala 2.10支援建構 。
3 叢集規劃
節點名稱 | IP | Zookeeper | Master | Worker |
node21 | 192.168.100.21 | | 主Master | |
node22 | 192.168.100.22 | | 備Master | |
node23 | 192.168.100.23 | |
二 叢集安裝
1 解壓縮
[admin@node21 software]$ tar zxvf spark-2.3.1-bin-hadoop2.7.tgz -C /opt/module/
[admin@node21 module]$ mv spark-2.3.1-bin-hadoop2.7 spark-2.3.1
2 修改配置檔案
(1)進入配置檔案所在目錄
[admin@node21 ~]$ cd /opt/module/spark-2.3.1/conf/
[admin@node21 conf]$ ll
total 36
-rw-rw-r-- 1 admin admin 996 Jun 2 04:49 docker.properties.template
-rw-rw-r-- 1 admin admin 1105 Jun 2 04:49 fairscheduler.xml.template
-rw-rw-r-- 1 admin admin 2025 Jun 2 04:49 log4j.properties.template
-rw-rw-r-- 1 admin admin 7801 Jun 2 04:49 metrics.properties.template
-rw-rw-r-- 1 admin admin 870 Jul 4 23:50 slaves.template
-rw-rw-r-- 1 admin admin 1292 Jun 2 04:49 spark-defaults.conf.template
-rwxrwxr-x 1 admin admin 4861 Jul 5 00:25 spark-env.sh.template
(2)複制spark-env.sh.template并重命名為spark-env.sh
[admin@node21 conf]$ cp spark-env.sh.template spark-env.sh
[admin@node21 conf]$ vi spark-env.sh
編輯并在檔案末尾添加如下配置内容
#指定預設master的ip或主機名
export SPARK_MASTER_HOST=node21
#指定maaster送出任務的預設端口為7077
export SPARK_MASTER_PORT=7077
#指定masster節點的webui端口
export SPARK_MASTER_WEBUI_PORT=8080
#每個worker從節點能夠支配的記憶體數
export SPARK_WORKER_MEMORY=1g
#允許Spark應用程式在計算機上使用的核心總數(預設值:所有可用核心)
export SPARK_WORKER_CORES=1
#每個worker從節點的執行個體(可選配置)
export SPARK_WORKER_INSTANCES=1
#指向包含Hadoop叢集的(用戶端)配置檔案的目錄,運作在Yarn上配置此項
export HADOOP_CONF_DIR=/opt/module/hadoop-2.7.6/etc/hadoop
#指定整個叢集狀态是通過zookeeper來維護的,包括叢集恢複
export SPARK_DAEMON_JAVA_OPTS="
-Dspark.deploy.recoveryMode=ZOOKEEPER
-Dspark.deploy.zookeeper.url=node21:2181,node22:2181,node23:2181
-Dspark.deploy.zookeeper.dir=/spark"
(3)複制slaves.template成slaves,并修改配置内容
[admin@node21 conf]$ cp slaves.template slaves
[admin@node21 conf]$ vi slaves
修改從節點
node22
node23
(4)将安裝包分發給其他節點
[admin@node21 module]$ scp -r spark-2.3.1 admin@node22:/opt/module/
[admin@node21 module]$ scp -r spark-2.3.1 admin@node23:/opt/module/
修改node22節點上conf/spark-env.sh配置的MasterIP為SPARK_MASTER_IP=node22
3 配置環境變量
所有節點均要配置
[admin@node21 spark-2.3.1]$ sudo vi /etc/profile
export SPARK_HOME=/opt/module/spark-2.3.1
export PATH=$PATH:$SPARK_HOME/bin:$SPARK_HOME/sbin
[admin@node21 spark-2.3.1]$ source /etc/profile
三 啟動叢集
1 啟動zookeeper叢集
所有zookeeper節點均要執行
[admin@node21 ~]$ zkServer.sh start
2 啟動Hadoop叢集
[admin@node21 ~]$ start-dfs.sh
[admin@node22 ~]$ start-yarn.sh
[admin@node23 ~]$ yarn-daemon.sh start resourcemanager
3 啟動Spark叢集
啟動spark:啟動master節點:sbin/start-master.sh 啟動worker節點:sbin/start-slaves.sh
或者:sbin/start-all.sh
[admin@node21 spark-2.3.1]$ sbin/start-all.sh
starting org.apache.spark.deploy.master.Master, logging to /opt/module/spark-2.3.1/logs/spark-admin-org.apache.spark.deploy.master.Master-1-node21.out
node22: starting org.apache.spark.deploy.worker.Worker, logging to /opt/module/spark-2.3.1/logs/spark-admin-org.apache.spark.deploy.worker.Worker-1-node22.out
node23: starting org.apache.spark.deploy.worker.Worker, logging to /opt/module/spark-2.3.1/logs/spark-admin-org.apache.spark.deploy.worker.Worker-1-node23.out
注意:備用master節點需要手動啟動
[admin@node22 spark-2.3.1]$ sbin/start-master.sh
starting org.apache.spark.deploy.master.Master, logging to /opt/module/spark-2.3.1/logs/spark-admin-org.apache.spark.deploy.master.Master-1-node22.out
4 檢視程序
[admin@node21 spark-2.3.1]$ jps
1316 QuorumPeerMain
3205 Jps
3110 Master
1577 DataNode
1977 DFSZKFailoverController
1788 JournalNode
2124 NodeManager
[admin@node22 spark-2.3.1]$ jps
1089 QuorumPeerMain
1233 DataNode
1617 ResourceManager
1159 NameNode
1319 JournalNode
1735 NodeManager
3991 Master
4090 Jps
1435 DFSZKFailoverController
3918 Worker
[admin@node23 spark-2.3.1]$ jps
1584 ResourceManager
1089 QuorumPeerMain
1241 JournalNode
2411 Worker
1164 DataNode
1388 NodeManager
2478 Jps
四 驗證叢集HA
1 看Web頁面Master狀态
node21是ALIVE狀态,node22為STANDBY狀态,WebUI檢視:http://node21:8080/
從節點連接配接位址:http://node22:8081/
2 驗證HA的高可用
手動幹掉node21上面的Master程序,node21:8080無法通路,node22:8080狀态如下,Master狀态成功自動進行切換。
3 HA注意點
- 主備切換過程中不能送出Application。
- 主備切換過程中不影響已經在叢集中運作的Application。因為Spark是粗粒度資源排程。
五叢集送出指令方式
1 Standalone模式
1.1 Standalone-client
(1)送出指令
[admin@node21 spark-2.3.1]$ ./bin/spark-submit --class org.apache.spark.examples.SparkPi \
--master spark://node21:7077 \
--executor-memory 500m \
--total-executor-cores 1 \
examples/jars/spark-examples_2.11-2.3.1.jar 10
或者
[admin@node21 spark-2.3.1]$ ./bin/spark-submit --class org.apache.spark.examples.SparkPi \
--master spark://node21:7077 \
--deploy-mode client \
--executor-memory 500m \
--total-executor-cores 1 \
examples/jars/spark-examples_2.11-2.3.1.jar 10
(2)送出原理圖解
(3)執行流程
- client模式送出任務後,會在用戶端啟動Driver程序。
- Driver會向Master申請啟動Application啟動的資源。
- 資源申請成功,Driver端将task發送到worker端執行。
- worker将task執行結果傳回到Driver端。
(4)總結
client模式适用于測試調試程式。Driver程序是在用戶端啟動的,這裡的用戶端就是指送出應用程式的目前節點。在Driver端可以看到task執行的情況。生産環境下不能使用client模式,是因為:假設要送出100個application到叢集運作,Driver每次都會在client端啟動,那麼就會導緻用戶端100次網卡流量暴增的問題。
1.2 Standalone-cluster
[admin@node21 spark-2.3.1]$ ./bin/spark-submit --class org.apache.spark.examples.SparkPi \
--master spark://node21:7077 \
--deploy-mode cluster \
examples/jars/spark-examples_2.11-2.3.1.jar 10
(3)執行流程
- cluster模式送出應用程式後,會向Master請求啟動Driver.
- Master接受請求,随機在叢集一台節點啟動Driver程序。
- Driver啟動後為目前的應用程式申請資源。
- Driver端發送task到worker節點上執行。
- worker将執行情況和執行結果傳回給Driver端。
Driver程序是在叢集某一台Worker上啟動的,在用戶端是無法檢視task的執行情況的。假設要送出100個application到叢集運作,每次Driver會随機在叢集中某一台Worker上啟動,那麼這100次網卡流量暴增的問題就散布在叢集上。
2 Yarn模式
2.1 yarn-client
以
client
模式啟動Spark應用程式:
$ ./bin/spark-submit --class path.to.your.Class --master yarn --deploy-mode client [options] <app jar> [app options]
例如
[admin@node21 spark-2.3.1]$ ./bin/spark-submit --class org.apache.spark.examples.SparkPi \
--master yarn \
--deploy-mode client \
examples/jars/spark-examples_2.11-2.3.1.jar 10
- 用戶端送出一個Application,在用戶端啟動一個Driver程序。
- 應用程式啟動後會向RS(ResourceManager)發送請求,啟動AM(ApplicationMaster)的資源。
- RS收到請求,随機選擇一台NM(NodeManager)啟動AM。這裡的NM相當于Standalone中的Worker節點。
- AM啟動後,會向RS請求一批container資源,用于啟動Executor.
- RS會找到一批NM傳回給AM,用于啟動Executor。
- AM會向NM發送指令啟動Executor。
- Executor啟動後,會反向注冊給Driver,Driver發送task到Executor,執行情況和結果傳回給Driver端。
Yarn-client模式同樣是适用于測試,因為Driver運作在本地,Driver會與yarn叢集中的Executor進行大量的通信,會造成客戶機網卡流量的大量增加.
ApplicationMaster的作用:
- 為目前的Application申請資源
- 給NodeManager發送消息啟動Executor。
注意:ApplicationMaster有launchExecutor和申請資源的功能,并沒有作業排程的功能。
2.2 yarn-cluster
cluster
$ ./bin/spark-submit --class path.to.your.Class --master yarn --deploy-mode cluster [options] <app jar> [app options]
[admin@node21 spark-2.3.1]$ ./bin/spark-submit --class org.apache.spark.examples.SparkPi \
--master yarn \
--deploy-mode cluster \
examples/jars/spark-examples_2.11-2.3.1.jar 10
- 客戶機送出Application應用程式,發送請求到RS(ResourceManager),請求啟動AM(ApplicationMaster)。
- RS收到請求後随機在一台NM(NodeManager)上啟動AM(相當于Driver端)。
- AM啟動,AM發送請求到RS,請求一批container用于啟動Executor。
- RS傳回一批NM節點給AM。
- AM連接配接到NM,發送請求到NM啟動Executor。
- Executor反向注冊到AM所在的節點的Driver。Driver發送task到Executor。
Yarn-Cluster主要用于生産環境中,因為Driver運作在Yarn叢集中某一台nodeManager中,每次送出任務的Driver所在的機器都是随機的,不會産生某一台機器網卡流量激增的現象,缺點是任務送出後不能看到日志。隻能通過yarn檢視日志。
ApplicationMaster的作用:
- 給NodeManager發送消息啟動Excutor。
- 任務排程。
停止叢集任務指令:yarn application -kill applicationID
六 配置曆史伺服器
1 臨時配置
對本次送出的應用程式起作用
./spark-shell --master spark://node21:7077
--name myapp1
--conf spark.eventLog.enabled=true
--conf spark.eventLog.dir=hdfs://node21:8020/spark/test
停止程式,在Web Ui中Completed Applications對應的ApplicationID中能檢視history。
2 永久配置
spark-default.conf配置檔案中配置HistoryServer,對所有送出的Application都起作用
在用戶端節點,進入../spark-2.3.1/conf/ spark-defaults.conf最後加入:
//開啟記錄事件日志的功能
spark.eventLog.enabled true
//設定事件日志存儲的目錄
spark.eventLog.dir hdfs://node21:8020/spark/test
//設定HistoryServer加載事件日志的位置
spark.history.fs.logDirectory hdfs://node21:8020/spark/test
//日志優化選項,壓縮日志
spark.eventLog.compress true
啟動HistoryServer:
./start-history-server.sh
通路HistoryServer:node21:18080,之後所有送出的應用程式運作狀況都會被記錄。
七 故障問題
1 Worker節點無法啟動
[admin@node21 spark-2.3.1]$ sbin/start-all.sh
starting org.apache.spark.deploy.master.Master, logging to /opt/module/spark-2.3.1/logs/spark-admin-org.apache.spark.deploy.master.Master-1-node21.out
node23: starting org.apache.spark.deploy.worker.Worker, logging to /opt/module/spark-2.3.1/logs/spark-admin-org.apache.spark.deploy.worker.Worker-1-node23.out
node22: starting org.apache.spark.deploy.worker.Worker, logging to /opt/module/spark-2.3.1/logs/spark-admin-org.apache.spark.deploy.worker.Worker-1-node22.out
node23: failed to launch: nice -n 0 /opt/module/spark-2.3.1/bin/spark-class org.apache.spark.deploy.worker.Worker --webui-port 8081 --port 7078 spark://node21:7077
node23: full log in /opt/module/spark-2.3.1/logs/spark-admin-org.apache.spark.deploy.worker.Worker-1-node23.out
node22: failed to launch: nice -n 0 /opt/module/spark-2.3.1/bin/spark-class org.apache.spark.deploy.worker.Worker --webui-port 8081 --port 7078 spark://node21:7077
node22: full log in /opt/module/spark-2.3.1/logs/spark-admin-org.apache.spark.deploy.worker.Worker-1-node22.out
由于之前在conf/spark-env.sh裡配置了如下資訊
#每個worker從節點的端口(可選配置)
export SPARK_WORKER_PORT=7078
#每個worker從節點的wwebui端口(可選配置)
export SPARK_WORKER_WEBUI_PORT=8081
可能是由于端口問題去掉上述兩項配置,重新開機成功。
2 啟動Spark on YARN報錯
2.1 Caused by: java.net.ConnectException: Connection refused
[admin@node21 spark-2.3.1]$ spark-shell --master yarn --deploy-mode client
報錯原因:記憶體資源給的過小,yarn直接kill掉程序,則報rpc連接配接失敗、ClosedChannelException等錯誤。
解決方法:先停止YARN服務,然後修改yarn-site.xml,增加如下内容
<!--是否将對容器強制實施虛拟記憶體限制 -->
<property>
<name>yarn.nodemanager.vmem-check-enabled</name>
<value>false</value>
</property>
<!--設定容器的記憶體限制時虛拟記憶體與實體記憶體之間的比率 -->
<property>
<name>yarn.nodemanager.vmem-pmem-ratio</name>
<value>4</value>
</property>
将新的yarn-site.xml檔案分發到其他Hadoop節點對應的目錄下,最後在重新啟動YARN。
重新執行以下指令啟動spark on yarn,啟動成功
2.2 java.lang.ClassNotFoundException: org.apache.spark.examples.SparkPi
[admin@node21 spark-2.3.1]$ ./bin/spark-submit --class org.apache.spark.examples.SparkPi \
> --master yarn \
> --deploy-mode client \
> examples/jars/spark-examples_2.11-2.3.1.jar 10
報錯資訊如下:
2018-07-13 05:19:14 WARN NativeCodeLoader:62 - Unable to load native-hadoop library for your platform... using builtin-java classes where applicable
java.lang.ClassNotFoundException: org.apache.spark.examples.SparkPi
at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:348)
at org.apache.spark.util.Utils$.classForName(Utils.scala:238)
at org.apache.spark.deploy.SparkSubmit$.org$apache$spark$deploy$SparkSubmit$$runMain(SparkSubmit.scala:851)
at org.apache.spark.deploy.SparkSubmit$.doRunMain$1(SparkSubmit.scala:198)
at org.apache.spark.deploy.SparkSubmit$.submit(SparkSubmit.scala:228)
at org.apache.spark.deploy.SparkSubmit$.main(SparkSubmit.scala:137)
at org.apache.spark.deploy.SparkSubmit.main(SparkSubmit.scala)
2018-07-13 05:19:15 INFO ShutdownHookManager:54 - Shutdown hook called
2018-07-13 05:19:15 INFO ShutdownHookManager:54 - Deleting directory /tmp/spark-d0c9c44a-40bc-4220-958c-c2f976361d64
解決方法: