一 下載安裝包
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 | Zookeeper |
主Master | |
node22 | 192.168.100.22 | Zookeeper |
備Master | Worker |
node23 | 192.168.100.23 | Zookeeper |
Worker |
二 集群安裝
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
(1)提交命令
[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
(2)提交原理圖解
(3)執行流程
- cluster模式提交應用程序后,會向Master請求啟動Driver.
- Master接受請求,隨機在集群一台節點啟動Driver進程。
- Driver啟動后為當前的應用程序申請資源。
- Driver端發送task到worker節點上執行。
- worker將執行情況和執行結果返回給Driver端。
(4)總結
Driver進程是在集群某一台Worker上啟動的,在客戶端是無法查看task的執行情況的。假設要提交100個application到集群運行,每次Driver會隨機在集群中某一台Worker上啟動,那么這100次網卡流量暴增的問題就散布在集群上。
2 Yarn模式
2.1 yarn-client
(1)提交命令
以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
(2)提交原理圖解
(3)執行流程
- 客戶端提交一個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端。
(4)總結
Yarn-client模式同樣是適用於測試,因為Driver運行在本地,Driver會與yarn集群中的Executor進行大量的通信,會造成客戶機網卡流量的大量增加.
ApplicationMaster的作用:
- 為當前的Application申請資源
- 給NodeManager發送消息啟動Executor。
注意:ApplicationMaster有launchExecutor和申請資源的功能,並沒有作業調度的功能。
2.2 yarn-cluster
(1)提交命令
以cluster
模式啟動Spark應用程序:
$ ./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
(2)提交原理圖解
(3)執行流程
- 客戶機提交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。
(4)總結
Yarn-Cluster主要用於生產環境中,因為Driver運行在Yarn集群中某一台nodeManager中,每次提交任務的Driver所在的機器都是隨機的,不會產生某一台機器網卡流量激增的現象,缺點是任務提交后不能看到日志。只能通過yarn查看日志。
ApplicationMaster的作用:
- 為當前的Application申請資源
- 給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
解決方法: