轉(zhuǎn)載請(qǐng)注明出處者甲,謝謝合作~
部署的子模塊暫時(shí)只提供 Standalone 和 Yarn瓢颅,k8s 我不會(huì)救巷,Mesos 沒(méi)用過(guò)
集群部署
集群模式概覽
本文檔對(duì) Spark 如何在集群上運(yùn)行作一個(gè)簡(jiǎn)單的介紹幌墓,來(lái)幫助理解其中所包含的各個(gè)組件何暇。如何在集群上啟動(dòng)應(yīng)用程序參見(jiàn)文檔 application submission guide陶夜。
組件
Spark 應(yīng)用程序在集群中運(yùn)行時(shí),表現(xiàn)為一組進(jìn)程集裆站,由主程序(也被叫做 driver program)中的 SparkContext
對(duì)象作協(xié)調(diào)条辟。
特別是,當(dāng)程序運(yùn)行在一個(gè)集群上時(shí)宏胯,SparkContext
對(duì)象可以和不同類型的集群管理器(Spark 自己的獨(dú)立集群管理器羽嫡,Mesos 或者 Yarn)進(jìn)行連接,為應(yīng)用程序分配需要的資源肩袍。一旦連接成功杭棵,Spark 就向集群中的節(jié)點(diǎn)申請(qǐng)進(jìn)行計(jì)算和數(shù)據(jù)存儲(chǔ)的 executor。接下來(lái)氛赐,driver 將應(yīng)用程序代碼(由 SparkContext
傳遞的 JAR 文件或者 Python 文件)發(fā)送給 executor魂爪,最后,SparkContext
發(fā)送子任務(wù)給 executor 運(yùn)行艰管。
對(duì)于這種架構(gòu)有一些有用的點(diǎn)需要注意:
- 每個(gè)應(yīng)用程序都有屬于自己的 executor 進(jìn)程滓侍,在整個(gè)應(yīng)用程序運(yùn)行期間一直待命,啟動(dòng)多個(gè)線程運(yùn)行子任務(wù)牲芋。這種方式可以在調(diào)度端(每個(gè) driver 調(diào)度自己的子任務(wù))和執(zhí)行端(不同應(yīng)用程序的子任務(wù)運(yùn)行在不同的 JVM 內(nèi))同時(shí)做到多個(gè)應(yīng)用程序之間的資源隔離撩笆。然而捺球,這也意味著除非寫(xiě)出到外部存儲(chǔ)系統(tǒng),數(shù)據(jù)無(wú)法在不同的 Spark 應(yīng)用程序(不同的
SparkContext
實(shí)例)之間共享夕冲。 - 下層的集群管理器對(duì) Spark 應(yīng)用程序來(lái)說(shuō)是透明的氮兵。只要應(yīng)用程序還能夠申請(qǐng)到 executor 進(jìn)程,這些進(jìn)程之間還可以互相通信耘擂,就可以輕松的在一個(gè)支持其他應(yīng)用類型的集群管理器上運(yùn)行(例如胆剧,Mesos/YARN)絮姆。
- driver 程序必須監(jiān)聽(tīng)和接收所屬 executor 進(jìn)程在整個(gè)生命周期內(nèi)傳遞的消息(參見(jiàn) spark.driver.port in the network config section)醉冤。所以,driver 程序?qū)τ?worker 節(jié)點(diǎn)必須是網(wǎng)絡(luò)可達(dá)的篙悯。
- 因?yàn)?driver 在集群中調(diào)度子任務(wù)蚁阳,它所運(yùn)行的節(jié)點(diǎn)應(yīng)該和 worker 節(jié)點(diǎn)足夠近,最好在同一個(gè)網(wǎng)絡(luò)平面內(nèi)鸽照。如果需要向遠(yuǎn)程集群發(fā)送請(qǐng)求螺捐,最好通過(guò) RPC 的方式來(lái)運(yùn)行 driver,就近運(yùn)行 driver 及其 executor矮燎,而不是讓 driver 程序離 worker 節(jié)點(diǎn)很遠(yuǎn)定血。
集群模式類型
目前支持一下幾種集群管理器:
- Standalone – Spark 中包含的一個(gè)簡(jiǎn)單的集群管理器,可以輕松部署管理一個(gè)集群诞外。
- Apache Mesos – 一個(gè)通用的集群管理器澜沟,也可以運(yùn)行 Hadoop MapReduce 應(yīng)用程序。
- Hadoop YARN – Hadoop 2 中的集群資源管理器峡谊。
- Kubernetes – 一個(gè)開(kāi)源的容器編排工具茫虽,可以自動(dòng)部署,彈性擴(kuò)容既们,容器化的管理應(yīng)用程序濒析。
還有一個(gè)第三方項(xiàng)目(非 Spark 項(xiàng)目提供支持)提供了將 Nomad 作為集群管理器的支持。
提交應(yīng)用程序
可以通過(guò) spark-submit
腳本提交應(yīng)用程序到任何類型的集群上啥纸。詳情參見(jiàn) application submission guide号杏。
監(jiān)控
每一個(gè) driver 程序都有自己的 web UI,通常端口是 4040斯棒,展示了正在運(yùn)行的子任務(wù)盾致,executor 和存儲(chǔ)管理的信息,可以通過(guò)瀏覽器輸入地址 http://<driver-node>:4040
來(lái)訪問(wèn)名船。監(jiān)控指南文檔還介紹了其他的監(jiān)控方式绰上。
Each driver program has a web UI, typically on port 4040, that displays information about running tasks, executors, and storage usage. Simply go to http://<driver-node>:4040
in a web browser to access this UI. The monitoring guide also describes other monitoring options.
作業(yè)調(diào)度
Spark 對(duì)應(yīng)用程序間(在集群資源管理器層面)以及應(yīng)用程序內(nèi)部(如果多個(gè)計(jì)算任務(wù)在一個(gè) SparkContext 中同時(shí)運(yùn)行)都提供了資源分配的控制。詳情參見(jiàn) job scheduling overview渠驼。
術(shù)語(yǔ)
下面的表格總結(jié)了集群模式中用到的概念術(shù)語(yǔ):
Term | Meaning |
---|---|
Application | 構(gòu)建于 Spark 之上的用戶應(yīng)用程序蜈块,由一個(gè) driver 程序和多個(gè)在集群上運(yùn)行的 executor 構(gòu)成。 |
Application jar | 包含 Spark 應(yīng)用程序的 Jar 文件。在一些場(chǎng)景下百揭,用戶可能需要?jiǎng)?chuàng)建一個(gè)「超級(jí) Jar 文件」爽哎,其中包含應(yīng)用程序和相關(guān)的依賴,但是其中不應(yīng)該加入 Hadoop 或者 Spark 相關(guān)的依賴庫(kù)器一,這些依賴會(huì)在運(yùn)行時(shí)由 Spark 提供课锌。 |
Driver program | 運(yùn)行應(yīng)用程序 main 方法的進(jìn)程,其中會(huì)創(chuàng)建 SparkContext 對(duì)象祈秕。 |
Cluster manager | 一個(gè)外部的管理集群資源的服務(wù)渺贤。(例如,獨(dú)立集群管理器请毛,Mesos志鞍,Yarn) |
Deploy mode | 區(qū)分 driver 進(jìn)程在哪里運(yùn)行。在「cluster」模式下方仿,Spark 會(huì)在集群內(nèi)啟動(dòng) driver 程序固棚,在「client」模式下,Spark 會(huì)在集群外啟動(dòng) driver 程序仙蚜。 |
Worker node | 集群中可以運(yùn)行應(yīng)用程序的節(jié)點(diǎn)此洲。 |
Executor | 在 worker 節(jié)點(diǎn)啟動(dòng)的應(yīng)用程序進(jìn)程,執(zhí)行子任務(wù)委粉,并將計(jì)算數(shù)據(jù)保存在內(nèi)存或者硬盤(pán)上呜师。每個(gè)應(yīng)用程序都有自己的 executor。 |
Task | 發(fā)送到 executor 執(zhí)行的一個(gè)計(jì)算單元艳丛。 |
Job | 一組并行計(jì)算的子任務(wù)構(gòu)成工作單元匣掸,由 Spark 中的 action 算子(例如,save 氮双,collect )觸發(fā)碰酝;可以在 driver 的日志中觀察到此術(shù)語(yǔ)。 |
Stage | 每一個(gè) job 都會(huì)被劃分為小的子任務(wù)集戴差,被叫做 stage送爸,它們之間有相互依賴的關(guān)系(類似于 MapReduce 中的 map 和 reduce 階段)壶笼;可以在 driver 的日志中觀察到此術(shù)語(yǔ)像捶。 |
提交應(yīng)用程序
Spark bin
目錄下的 spark-submit
腳本用來(lái)將一個(gè)應(yīng)用程序提交到集群。該腳本可以通過(guò)統(tǒng)一的接口使用所有 Spark 支持的集群管理器(cluster managers)媳纬,所以不需要為每個(gè)應(yīng)用程序作單獨(dú)配置球匕。
打包應(yīng)用程序依賴
如果你的代碼依賴其他項(xiàng)目纹磺,需要將這些依賴于自己的應(yīng)用程序打包在一起,Spark 會(huì)將 Jar 文件分發(fā)到集群上亮曹¢涎睿可以通過(guò)創(chuàng)建一個(gè)組合 Jar 文件(或者「超級(jí)」Jar 文件)來(lái)實(shí)現(xiàn)秘症,sbt 和 Maven 都有組合插件。在創(chuàng)建組合 Jar 文件時(shí)式矫,請(qǐng)將 Spark 和 Hadoop 相關(guān)的依賴標(biāo)記為 provided
乡摹,這些不需要被打包在一起,因?yàn)榧汗芾砥髟谶\(yùn)行時(shí)會(huì)提供采转。一旦打包好了組合 Jar 文件聪廉,可以調(diào)用 bin/spark-submit
腳本來(lái)傳遞 Jar 文件,如下所示故慈。
對(duì)于 Python板熊,可以使用 spark-submit
腳本的 --py-files
參數(shù)添加 .py
,.zip
或者 .egg
文件來(lái)分發(fā)應(yīng)用程序惯悠。如果依賴多個(gè) Python 文件邻邮,建議將它們壓縮為 .zip
或者 .egg
文件竣况。
使用 spark-submit 腳本啟動(dòng)應(yīng)用程序
一旦打包好一個(gè)應(yīng)用程序克婶,就可以使用 bin/spark-submit
腳本來(lái)啟動(dòng)。該腳本會(huì)處理好添加 Spark 相關(guān)的依賴丹泉,能夠支持不同的集群管理器和支持的部署模式:
./bin/spark-submit \
--class <main-class> \
--master <master-url> \
--deploy-mode <deploy-mode> \
--conf <key>=<value> \
... # other options
<application-jar> \
[application-arguments]
一些常用的參數(shù):
-
--class
:應(yīng)用程序入口主類(例如org.apache.spark.examples.SparkPi
) -
--master
:集群地址 master URL(例如spark://23.195.26.187:7077
) -
--deploy-mode
:是否將 driver 進(jìn)程部署到集群 worker 節(jié)點(diǎn)(cluster
)情萤,或者作為客戶端在集群外部運(yùn)行(client
),默認(rèn)為client
? -
--conf
:自定義的 Spark 配置項(xiàng)摹恨,格式為 key=value筋岛。對(duì)于包含空格的值,需要添加雙引號(hào) “key=value”晒哄,多個(gè)配置項(xiàng)應(yīng)該分開(kāi)設(shè)置(例如--conf <key>=<value> --conf <key2>=<value2>
) -
application-jar
:包含應(yīng)用程序和依賴的 Jar 文件路徑睁宰。URL 地址必須在集群中全局可見(jiàn),例如寝凌,一個(gè)hdfs://
路徑或者一個(gè)在所有節(jié)點(diǎn)都存在的file://
路徑 -
application-arguments
:傳遞給應(yīng)用程序主類的參數(shù)柒傻,如果有的話
?一個(gè)常用的部署策略就是從一個(gè)與 worker 節(jié)點(diǎn)物理上連接的網(wǎng)關(guān)節(jié)點(diǎn)上提交應(yīng)用程序(例如,在一個(gè)獨(dú)立 EC2 集群上的 Master 節(jié)點(diǎn))较木。此時(shí)红符,就是適合采用 client
部署模式,在 client
模式下伐债,driver 程序會(huì)作為集群的客戶端的角色由 spark-submit
腳本提交预侯。應(yīng)用程序的輸入和輸出被定向到控制臺(tái),所以峰锁,這種模式很適合 REPL(例如萎馅,Spark shell)。
另外虹蒋,如果從一個(gè)離 worker 節(jié)點(diǎn)很遠(yuǎn)的機(jī)器上提交應(yīng)用程序(例如糜芳,本地或者自己的筆記本)拣技,通常使用 cluster
模式來(lái)最小化 driver 和 executor 之間的網(wǎng)絡(luò)延遲。目前耍目,獨(dú)立集群部署方式不支持 Python 應(yīng)用的集群提交模式膏斤。
對(duì)于 Python 應(yīng)用程序,請(qǐng)將原本在 <application-jar>
位置的 Jar 文件替換為 .py
文件邪驮,通過(guò) --py-files
參數(shù)添加 .zip
莫辨,.egg
或者 .py
文件。
有一些與集群管理器(cluster manager)相關(guān)的特定選項(xiàng)毅访,例如沮榜,對(duì)于 Spark 獨(dú)立集群(Spark standalone cluster)部署模式下的 cluster
提交模式,可以指定 --supervise
參數(shù)來(lái)讓 driver 進(jìn)程在異常退出的情況下自動(dòng)重啟喻粹◇∪冢可以通過(guò) --help
參數(shù)列舉出 spark-submit
腳本所有可用的參數(shù)選項(xiàng)。下面是一些常用的參數(shù)選項(xiàng):
# Run application locally on 8 cores
./bin/spark-submit \
--class org.apache.spark.examples.SparkPi \
--master local[8] \
/path/to/examples.jar \
100
# Run on a Spark standalone cluster in client deploy mode
./bin/spark-submit \
--class org.apache.spark.examples.SparkPi \
--master spark://207.184.161.138:7077 \
--executor-memory 20G \
--total-executor-cores 100 \
/path/to/examples.jar \
1000
# Run on a Spark standalone cluster in cluster deploy mode with supervise
./bin/spark-submit \
--class org.apache.spark.examples.SparkPi \
--master spark://207.184.161.138:7077 \
--deploy-mode cluster \
--supervise \
--executor-memory 20G \
--total-executor-cores 100 \
/path/to/examples.jar \
1000
# Run on a YARN cluster
export HADOOP_CONF_DIR=XXX
./bin/spark-submit \
--class org.apache.spark.examples.SparkPi \
--master yarn \
--deploy-mode cluster \ # can be client for client mode
--executor-memory 20G \
--num-executors 50 \
/path/to/examples.jar \
1000
# Run a Python application on a Spark standalone cluster
./bin/spark-submit \
--master spark://207.184.161.138:7077 \
examples/src/main/python/pi.py \
1000
# Run on a Mesos cluster in cluster deploy mode with supervise
./bin/spark-submit \
--class org.apache.spark.examples.SparkPi \
--master mesos://207.184.161.138:7077 \
--deploy-mode cluster \
--supervise \
--executor-memory 20G \
--total-executor-cores 100 \
http://path/to/examples.jar \
1000
# Run on a Kubernetes cluster in cluster deploy mode
./bin/spark-submit \
--class org.apache.spark.examples.SparkPi \
--master k8s://xx.yy.zz.ww:443 \
--deploy-mode cluster \
--executor-memory 20G \
--num-executors 50 \
http://path/to/examples.jar \
1000
Master URLs
傳遞給 Spark 的 master URL 可以是以下幾種格式之一:
Master URL | Meaning |
---|---|
local |
啟用一個(gè) worker 線程在本地運(yùn)行 Spark 應(yīng)用程序(即守呜,沒(méi)有并行計(jì)算)型酥。 |
local[K] |
啟動(dòng) K 個(gè) worker 線程在本地運(yùn)行 Spark 應(yīng)用程序(最好將該值設(shè)置為運(yùn)行宿主機(jī)的核數(shù))。 |
local[K,F] |
啟動(dòng) K 個(gè) worker 線程在本地運(yùn)行 Spark 應(yīng)用程序查乒,并允許 F 個(gè)線程執(zhí)行失斆趾怼(對(duì)該參數(shù)的解釋參見(jiàn) spark.task.maxFailures)。 |
local[*] |
啟動(dòng)本機(jī)邏輯核心數(shù)個(gè) worker 線程在本地運(yùn)行 Spark 應(yīng)用程序玛迄。 |
local[*,F] |
啟動(dòng)本機(jī)邏輯核心數(shù)個(gè) worker 線程在本地運(yùn)行 Spark 應(yīng)用程序由境,并允許 F 個(gè)線程執(zhí)行失敗。 |
spark://HOST:PORT |
連接到指定的 Spark 獨(dú)立集群(Spark standalone cluster)的 master 節(jié)點(diǎn)蓖议。端口必須是正在使用的配置端口虏杰,默認(rèn)為 7077。 |
spark://HOST1:PORT1,HOST2:PORT2 |
連接到指定的通過(guò) Zookeeper 開(kāi)啟了高可用的 Spark 獨(dú)立集群(Spark standalone cluster with standby masters with Zookeeper)勒虾。端口必須是正在使用的配置端口纺阔,默認(rèn)為 7077。 |
mesos://HOST:PORT |
連接到指定的 Mesos 集群从撼。端口必須是正在使用的配置端口州弟,默認(rèn)為 5050〉土悖或者婆翔,對(duì)于使用 Zookeeper 的 Mesos 集群,可以使用 mesos://zk://... 掏婶。如果需要以 cluster 模式 --deploy-mode cluster 提交應(yīng)用程序啃奴,HOST 和 PORT 需要配置連接到 MesosClusterDispatcher。 |
yarn |
以 client 或者 cluster 模式連接到 YARN 集群雄妥,提交模式取決于參數(shù)選項(xiàng) --deploy-mode 最蕾。集群地址將會(huì)從環(huán)境變量 HADOOP_CONF_DIR 或者 YARN_CONF_DIR 目錄下的配置文件中獲取依溯。 |
k8s://HOST:PORT |
以 cluster 模式連接到 Kubernetes 集群。目前還不支持模client 式瘟则,將會(huì)在未來(lái)的版本中提供黎炉。其中 HOST 和 PORT 參見(jiàn) Kubernetes API Server。默認(rèn)情況下開(kāi)啟 TLS醋拧,如果需要非安全的連接慷嗜,可以使用 k8s://http://HOST:PORT 。 |
從文件中加載配置
spark-submit
腳本可以從一個(gè) kv 格式的傳遞給應(yīng)用程序的屬性文件中加載默認(rèn)的配置項(xiàng)(Spark configuration values)丹壕,默認(rèn)情況下庆械,會(huì)讀取 Spark 目錄下的 conf/spark-defaults.conf
文件,更多詳情參見(jiàn) loading default configurations菌赖。
從默認(rèn)配置文件中加載配置可以避免向 spark-submit
腳本傳遞一些常規(guī)的參數(shù)缭乘,比如,如果配置文件中配置了 spark.master
參數(shù)琉用,就可以省略 spark-submit
腳本中的 --master
選項(xiàng)堕绩。一般來(lái)說(shuō),在 SparkConf
對(duì)象中顯示定義的配置的優(yōu)先級(jí)最高辕羽,其次是通過(guò) spark-submit
腳本傳遞的配置逛尚,最后才是默認(rèn)配置文件中的配置項(xiàng)。
如果還是不清楚配置項(xiàng)是從哪里獲取的刁愿,可以為 spark-submit
腳本提供 --verbose
選項(xiàng)來(lái)打印細(xì)粒度的調(diào)試信息。
高級(jí)依賴管理
在使用 spark-submit
腳本時(shí)到逊,應(yīng)用程序 Jar 文件以及通過(guò) --jars
選項(xiàng)指定的 Jar 文件都會(huì)自動(dòng)分發(fā)到集群中去铣口。--jars
選項(xiàng)指定的 URL 必須以逗號(hào)分隔,其中每一項(xiàng)都會(huì)被添加到 driver 和 executor 的 classpath 中去觉壶。--jars
選項(xiàng)不支持目錄展開(kāi)脑题。
Spark 可以通過(guò)下面不同方式的的 URL 模式來(lái)指定需要分發(fā)的 Jar 文件:
-
file: - 絕對(duì)路徑,
file:/
URI 由 driver 的 HTTP 文件服務(wù)器管理铜靶,每個(gè) executor 都從 driver 的 HTTP 服務(wù)拉取依賴叔遂。 - hdfs:, http:, https:, ftp: - 這些模式將 Jar 文件從相應(yīng)的 URI 中獲取。
-
local: - 以
local:/
為模式的 URI 會(huì)被當(dāng)做在每個(gè) worker 節(jié)點(diǎn)上都存在相同的本地文件争剿,這就意味著不會(huì)發(fā)生網(wǎng)絡(luò) IO已艰,要比把一個(gè)大文件分發(fā)到每個(gè)節(jié)點(diǎn),或者通過(guò) NFS蚕苇,GlusterFS 共享要高效哩掺。
注意,Jar 和其他文件會(huì)被復(fù)制到每個(gè) executor 節(jié)點(diǎn)上 SparkContext 的工作目錄涩笤,有可能會(huì)占用很大的空間嚼吞,需要在適當(dāng)?shù)臅r(shí)候清理盒件。對(duì)于 Yarn 來(lái)說(shuō),清理操作是自動(dòng)的舱禽,對(duì)于 Spark 獨(dú)立集群管理器炒刁,需要通過(guò)配置 spark.worker.cleanup.appDataTtl
屬性來(lái)開(kāi)啟自動(dòng)清理。
用戶還可以通過(guò) --packages
選項(xiàng)提供以逗號(hào)分隔的 Maven 坐標(biāo)來(lái)添加其他依賴誊稚,所有傳遞性依賴都可以通過(guò)這種方式管理切心。額外的倉(cāng)庫(kù)(或者 SBT resolver)可以通過(guò) --repositories
選項(xiàng)提供,倉(cāng)庫(kù)地址以逗號(hào)分隔片吊。(注意绽昏,有密碼保護(hù)的倉(cāng)庫(kù)可以通過(guò)倉(cāng)庫(kù) URI 來(lái)提供密匙,例如 https://user:password@host/...
俏脊,但是請(qǐng)謹(jǐn)慎使用)全谤。以上選項(xiàng)可以被 pyspark
,spark-shell
和 spark-submit
命令使用來(lái)添加依賴爷贫。
對(duì)于 Python认然,--py-files
選項(xiàng)可以用來(lái)分發(fā) .egg
,.zip
和 .py
依賴庫(kù)到 executor漫萄。
更多信息
一旦部署了自己的應(yīng)用程序卷员,文檔 cluster mode overview 介紹了分布式執(zhí)行過(guò)程中參與的組件,以及如何監(jiān)控和調(diào)試應(yīng)用程序腾务。