啟動(dòng)SparkOnYARN
確認(rèn)HADOOP_CONF_DIR或者YARN_CONF_DIR指向的目錄包含Hadoop集群的配置文件。Spark依賴這些配置文件的內(nèi)容寫(xiě)HDFS或者向YARN申請(qǐng)資源叠聋。這些配置需要復(fù)制到Spark集群內(nèi)所有的機(jī)器上炸卑,來(lái)保證整個(gè)集群使用的是同一套配置黎茎。如果配置中的Java系統(tǒng)變量或者環(huán)境變量不是YARN支持的,他們應(yīng)該被設(shè)置到Spark應(yīng)用的配置中(driver速梗、executor和Application Master)
使用YARN啟動(dòng)Spark應(yīng)用有兩種模式(cluster和client)钞啸。在cluster模式下,Spark應(yīng)用的Driver端根據(jù)YARN的調(diào)度運(yùn)行在Application Master進(jìn)程中逾一,在啟動(dòng)Spark應(yīng)用之后铸本,客戶端就可以直接退出了。在client模式下遵堵,Driver端運(yùn)行在客戶端進(jìn)程里箱玷,Application Master只用來(lái)向YARN申請(qǐng)資源。
和standalone以及mesos模式不一樣陌宿,在YARN模式下锡足,ResourceManager的地址是從Hadoop配置文件中讀到的,所以 --master 參數(shù)要設(shè)置值為 "yarn"壳坪,以集群模式啟動(dòng)Spark應(yīng)用需要這樣寫(xiě)
./bin/spark-submit --class path.to.your.Class --master yarn --deploy-mode cluster [options] <app jar> [app options]
例如
./bin/spark-submit --class org.apache.spark.examples.SparkPi \
--master yarn \
--deploy-mode cluster \
--driver-memory 4g \
--executor-memory 2g \
--executor-cores 1 \
--queue thequeue \
lib/spark-examples*.jar \
10
上面這行命令啟動(dòng)了一個(gè)YARN的client程序舶得,這個(gè)程序會(huì)啟動(dòng)一個(gè)默認(rèn)的Application Master。 SparkPi這個(gè)類(lèi)會(huì)作為Application Master進(jìn)程的一個(gè)線程執(zhí)行爽蝴°迮客戶端可以定期的從Application Master拉取一些統(tǒng)計(jì)信息纫骑,然后把這些信息顯示在控制臺(tái)上。當(dāng)Spark應(yīng)用執(zhí)行完畢的時(shí)候這個(gè)client會(huì)自動(dòng)退出九孩。
以client模式啟動(dòng)一個(gè)Spark應(yīng)用和前面差不多先馆,只是把deploy-mode參數(shù)的cluster替換成client,下面這個(gè)行命令是使用client模式啟動(dòng)spark-shell
./bin/spark-shell --master yarn --deploy-mode client
添加其他JAR
cluster模式下躺彬,因?yàn)镈river端運(yùn)行在其他機(jī)器上煤墙,所以代碼里寫(xiě)SparkContext.addJar是沒(méi)用的(client模式才可以這樣寫(xiě))。如果cluster模式下我們還有這個(gè)需求宪拥,我們要把想添加的jar文件用--jars參數(shù)拼在啟動(dòng)命令里仿野。
./bin/spark-submit --class my.main.Class \
--master yarn \
--deploy-mode cluster \
--jars my-other-jar.jar,my-other-other-jar.jar \
my-main-jar.jar \
app_arg1 app_arg2
準(zhǔn)備
想要使用Spark on YARN需要有Spark獨(dú)立的構(gòu)建結(jié)果。官網(wǎng)上提供了下載地址她君,如果想要自己去構(gòu)建一把也可以设预,相關(guān)信息在這里
配置
Spark on YARN模式的配置項(xiàng)大多數(shù)和另外兩種一樣。關(guān)于on YARN模式的特殊配置可以看這里
調(diào)試Spark應(yīng)用
在YARN的屬于里犁河,executor和application master都運(yùn)行在YARN的容器內(nèi)鳖枕。在Spark應(yīng)用執(zhí)行完畢后YARN有兩種方式來(lái)管理容器內(nèi)的日志。如果日志聚集功能打開(kāi)(使用 yarn.log-aggregation-enable 配置項(xiàng)),容器日志會(huì)被復(fù)制到HDFS桨螺,并從所在的機(jī)器上刪除宾符。這些日志可以使用yarn logs命令在集群內(nèi)的任意一臺(tái)節(jié)點(diǎn)上查看
yarn logs -applicationId <app ID>
這條命令會(huì)打印這個(gè)應(yīng)用(其實(shí)是Spark應(yīng)用,但YARN是一個(gè)獨(dú)立的資源調(diào)度與任務(wù)監(jiān)控工具灭翔,只要符合它的規(guī)范魏烫,任何應(yīng)用都可以使用YARN來(lái)做資源調(diào)度和任務(wù)監(jiān)控,所以這里用了"應(yīng)用"兩個(gè)字而不是"Spark應(yīng)用")在所有容器實(shí)例內(nèi)的所有日志肝箱。我們也可以使用HDFS的API來(lái)直接查看日志哄褒。這些日志的存儲(chǔ)路徑使用yarn.nodemanager.remote-app-log-dir 和 yarn.nodemanager.remote-app-log-dir-suffix來(lái)配置,一個(gè)配置目錄煌张,一個(gè)配置文件后綴呐赡。這些日志還可以在Spark的WEB UI中的Executors 頁(yè)簽中查看。我們需要確保Spark History Server和MapReduce History Server都運(yùn)行正常骏融,并且早yarn-site.xml中配置了yarn.log.server.url屬性链嘀。Spark History Server的UI會(huì)把查看日志的動(dòng)作重定向到MapReduce History Server中來(lái)顯示聚合后的日志。
日志聚合沒(méi)打開(kāi)時(shí)档玻,日志會(huì)保存在每臺(tái)執(zhí)行的機(jī)器上怀泊,所在的目錄是YARN_APP_LOGS_DIR,這個(gè)一般被配置到/tmp/logs目錄或者$HADOOP_HOME/log/uiserlogs目錄(具體位置取決于Hadoop版本和安裝時(shí)的配置)误趴。我們可以到具體的機(jī)器上去查看指定目錄下的日志霹琼,子目錄被按照applicationid和containerid組織。日志同樣可以在Spark WEB UI中的Executors頁(yè)簽中查看,但此時(shí)不會(huì)重定向到MapReduce History Server了枣申。
想查看每個(gè)容器啟動(dòng)時(shí)的環(huán)境變量树灶,可以增加 yarn.nodemanager.delete.debug-delay-sec屬性的值(比如設(shè)置為36000)然后到運(yùn)行容器的機(jī)器上查看 yarn.nodemanager.local-dirs 目錄中的內(nèi)容。這個(gè)目錄中包含了啟動(dòng)容器的腳本糯而,jar包和所有的環(huán)境變量天通。這個(gè)騷操作在調(diào)試classpath和環(huán)境變量等問(wèn)題時(shí)非常有用。(注意熄驼,啟用此選項(xiàng)需要管理員權(quán)限才能進(jìn)行群集設(shè)置并重新啟動(dòng)所有節(jié)點(diǎn)管理器像寒。因此,這不適用于托管群集)瓜贾。
要為application master和 executor使用自定義的log4j配置诺祸,可以使用下面的選項(xiàng)
- 用spark-submit提交任務(wù)時(shí),使用 --files 來(lái)上傳一個(gè)自定義的log4j.properties
- 配置Spark集群的時(shí)候祭芦,把 spark.driver.extraJavaOptions(這個(gè)是給driver的)或者spark.executor.extraJavaOptions(這個(gè)是給executor的)配置上 -Dlog4j.configuration=<log4j.properties文件的絕對(duì)路徑>筷笨。注意,這樣做需要配置的時(shí)候把 file:// 這個(gè)協(xié)議寫(xiě)上龟劲,這個(gè)文件也需要放到集群中所有節(jié)點(diǎn)上
- 修改spark機(jī)器上配置文件目錄內(nèi)的log4j.properties(看樣子是不需要重啟了)胃夏,但要注意這個(gè)配置比前面兩個(gè)優(yōu)先級(jí)要低,互相沖突的時(shí)候這個(gè)文件內(nèi)的配置肯定不生效
需要注意的是:第一種方式的配置會(huì)讓Application Master和Executor使用相同的配置文件昌跌,當(dāng)ApplicationMaster和某個(gè)Executor在同一臺(tái)機(jī)器上的時(shí)候仰禀,可能會(huì)有一些問(wèn)題,因?yàn)樗麄冊(cè)谕瑫r(shí)操作同一個(gè)日志文件蚕愤。
如果我們需要設(shè)置一個(gè)適當(dāng)?shù)奈恢脕?lái)讓YARN放置答恶、聚合日志,在log4j.properties文件中使用spark.yarn.app.container.log.dir 來(lái)配置文件輸出位置萍诱,比如:
log4j.appender.file_appender.File=${spark.yarn.app.container.log.dir}/spark.log
如果是Streaming應(yīng)用悬嗓,需要配置 RollingFileAppender并且設(shè)置本地存儲(chǔ)路徑,來(lái)避免日志文件太大磁盤(pán)空間不足裕坊。
為Application Master和executor指定自定義的metrics.properties 包竹,這個(gè)文件在spark配置目錄中。對(duì)文件的修改會(huì)自動(dòng)被提交給集群碍庵,所以我們不需要每次啟動(dòng)Spark應(yīng)用手動(dòng)指定 --files 參數(shù)映企。
下面是Spark的屬性
名稱 | 默認(rèn)值 | 含義 |
---|---|---|
spark.yarn.am.memory | 512m | client模式下指定Application Master總的內(nèi)存大小,cluster模式下使用spark.driver.memory静浴。使用小寫(xiě)字母后綴來(lái)指定單位:k,m,g,t |
spark.yarn.am.cores | 1 | client模式下Application Master使用的cpu數(shù)量。cluster模式下用spark.driver.cores |
spark.yarn.am.waitTime | 100s | cluster模式下application master等待SparkContext被初始化的時(shí)間挤渐。client模式下application master等待driver連接的時(shí)間 |
spark.yarn.submit.file.replication | HDFS的副本數(shù) | Spark應(yīng)用提交的文件在HDFS中的副本數(shù)苹享,一般這些文件是:程序的jar和其他的分布式存儲(chǔ)的文件或歸檔文件 |
spark.yarn.stagingDir | 當(dāng)前用戶家目錄 | 提交應(yīng)用程序時(shí)使用的暫存目錄。 |
spark.yarn.preserve.staging.files | false | 當(dāng)Spark應(yīng)用結(jié)束的時(shí)候,緩存的jar和文件是否刪除得问。false為刪除囤攀,設(shè)置為true是不刪除 |
spark.yarn.scheduler.heartbeat.interval-ms | 3000 | application master到Y(jié)ARN resourcemanager的心跳間隔,單位是毫秒宫纬。這個(gè)值的上線時(shí)YARN配置的值的一半焚挠,也就是 yarn.am.liveness-monitor.expiry-interval-ms的值的一半 |
spark.yarn.scheduler.initial-allocation.interval | 200ms | 當(dāng)ResourceManager沒(méi)響應(yīng)ApplicationMaster請(qǐng)求的時(shí)候,重復(fù)請(qǐng)求的間隔漓骚。這個(gè)值不應(yīng)該比spark.yarn.scheduler.heartbeat.interval-ms大蝌衔。如果ResourceManager一直沒(méi)響應(yīng),ApplicationMaster會(huì)再次請(qǐng)求蝌蹂,直到得到反饋噩斟,或者總時(shí)間超過(guò)spark.yarn.scheduler.heartbeat.interval-ms值 |
spark.yarn.historyServer.address | 無(wú) | Spark History Server地址。 |
spark.yarn.dist.archives | 無(wú) | 會(huì)被復(fù)制到每個(gè)Executor所在機(jī)器上的歸檔 |
文件孤个,逗號(hào)分隔 | ||
spark.yarn.dist.files | 無(wú) | 會(huì)被復(fù)制到每個(gè)Executor所在機(jī)器上的文件剃允,逗號(hào)分隔 |
spark.yarn.dist.jars | 無(wú) | 會(huì)被復(fù)制到每個(gè)Executor所在機(jī)器上的jar文件,逗號(hào)分隔 |
spark.executor.instances | 2 | 靜態(tài)資源exector個(gè)數(shù)分配默認(rèn)值齐鲤。(Spark是靜態(tài)資源分配斥废,因?yàn)槲覀冃枰趫?zhí)行前確認(rèn)資源,不論命令行還是默認(rèn)配置都是預(yù)先分配)當(dāng)spark.dynamicAllocation.enabled為true時(shí)给郊,是動(dòng)態(tài)分配資源营袜,這種場(chǎng)景Streaming的情況更多,因?yàn)樾枰馁Y源和業(yè)務(wù)峰值相關(guān)丑罪。 |
spark.yarn.executor.memoryOverhead | executorMemory * 0.10,最少 384 | 每個(gè)executor分配的最少非堆內(nèi)存荚板,單位m。 |
spark.yarn.driver.memoryOverhead | driverMemory * 0.10, 最少384 | Driver端的非堆內(nèi)存吩屹,單位m |
spark.yarn.am.memoryOverhead | AM memory * 0.10, 最少384 | client模式下Application Master的非堆內(nèi)存 |
spark.yarn.am.port | 隨機(jī) | Application Master的端口跪另。client模式下,這個(gè)端口用于Driver端于ApplicationMaster的通信煤搜。cluster模式下用于接收調(diào)度程序的終止命令 |
spark.yarn.queue | default | 提交應(yīng)用程序的YARN隊(duì)列名稱 |
spark.yarn.jars | 無(wú) | 需要分發(fā)到Y(jié)ARN容器中的Spark代碼的jar包免绿,多個(gè)用逗號(hào)分隔。Spark on YARN中Spark默認(rèn)使用本地的Spark的jar擦盾,但是也可以把Spark的jar放到HDFS中全局可讀嘲驾,這樣Spark應(yīng)用程序使用這些jar的時(shí)候不需要每次都用 --jars 提交然后分發(fā)。 |
spark.yarn.archive | 無(wú) | 和spark.yarn.jars同樣原理 |
spark.yarn.access.namenodes | 無(wú) | Spark應(yīng)用程序可以訪問(wèn)的安全的HDFS的namenode節(jié)點(diǎn)列表迹卢,多個(gè)用逗號(hào)分隔spark.yarn.access.namenodes=hdfs://nn1.com:8032,hdfs://nn2.com:8032, webhdfs://nn3.com:50070辽故。關(guān)于權(quán)限和K8S相關(guān)信息我還不了解,以后再回來(lái)修改 |
spark.yarn.appMasterEnv.[EnvironmentVariableName] | 無(wú) | 把環(huán)境變量添加到Application Master所在的進(jìn)程中腐碱。在cluster模式下誊垢,這個(gè)環(huán)境變量可以被Driver端讀取到, client模式下這個(gè)變量只有啟動(dòng)Driver的程序可以讀取到 |
spark.yarn.containerLauncherMaxThreads | 25 | Application Master中用于啟動(dòng)執(zhí)行程序容器的最大線程數(shù) |
spark.yarn.am.extraJavaOptions | 無(wú) | Application Master啟動(dòng)的時(shí)候的JVM參數(shù)配置 |
spark.yarn.am.extraLibraryPath | 無(wú) | 在client模式下,啟動(dòng)Application Master的時(shí)候指定的jar加載路徑 |
spark.yarn.maxAppAttempts | yarn-site.xml中配置的yarn.resourcemanager.am.max-attempts 值 | 向YARN提交申請(qǐng)的時(shí)候最大的嘗試次數(shù)喂走,這個(gè)數(shù)字不應(yīng)該超過(guò)YARN中配置的值 |
spark.yarn.am.attemptFailuresValidityInterval | 無(wú) | Spark監(jiān)控ApplicationMaster的失敗次數(shù)殃饿,如果這個(gè)值配置了,當(dāng)ApplicationMaster運(yùn)行持續(xù)時(shí)間超過(guò)這個(gè)值的時(shí)候芋肠,失敗次數(shù)會(huì)被清零乎芳。這個(gè)屬性不配置的時(shí)候不會(huì)生效,并且要求Hadoop版本在2.6以上 |
spark.yarn.executor.failuresValidityInterval | 無(wú) | 定義了Executor執(zhí)行是否失敗的檢查間隔帖池,超過(guò)這個(gè)檢查間隔的錯(cuò)誤會(huì)被忽略 |
spark.yarn.submit.waitAppCompletion | true | yarn cluster模式下奈惑,這個(gè)屬性控制客戶端是否需要同步等待任務(wù)執(zhí)行完畢。如果設(shè)置為true碘裕,客戶端進(jìn)程會(huì)一直活著携取,并報(bào)告Spark應(yīng)用的當(dāng)前狀態(tài)。如果設(shè)置為false帮孔,則客戶端提交完畢后就立即退出 |
spark.yarn.am.nodeLabelExpression | 無(wú) | 聲明ApplicationMaster的節(jié)點(diǎn)標(biāo)簽表達(dá)式雷滋,目的是限制哪些節(jié)點(diǎn)可以作為ApplicationMaster節(jié)點(diǎn),但要求YARN版本在2.6以上 |
spark.yarn.executor.nodeLabelExpression | 無(wú) | 聲明Executor的節(jié)點(diǎn)標(biāo)簽表達(dá)式文兢,目的是限制哪些節(jié)點(diǎn)可以作為Executor節(jié)點(diǎn)晤斩,但要求YARN版本在2.6以上 |
to be continued
重要提示
- 請(qǐng)求是否被及時(shí)響應(yīng)依賴于當(dāng)前使用的scheduler,以及這個(gè)scheduler的配置方式
- 在cluster模式下姆坚,driver和executor使用的本地工作目錄是YARN中配置的yarn.nodemanager.local-dirs目錄下澳泵,用戶指定的spark.local.dir是不起作用的。在client模式下兼呵,只有executor和cluster模式下一樣兔辅,而Driver會(huì)使用spark.local.dir中的配置作為本地工作目錄。這是因?yàn)閏lient模式下Driver不是在YARN cluster里執(zhí)行的击喂。
- 使用--files參數(shù)提交文件到集群可以指定別名维苔,例如 --files localtest.txt#appSees.txt 這是會(huì)把localtest.txt提交到HDFS里,但是想要訪問(wèn)這個(gè)文件需要使用appSees.txt這個(gè)名字懂昂。
- cluster模式下介时,可以用--jars來(lái)實(shí)現(xiàn)SparkContext.addJar的功能。
在安全集群中運(yùn)行
TODO
給YARN配置外部Shuffle服務(wù)
這部分因?yàn)槲也涣私釿ARN凌彬,所以不是很明白沸柔。以后了解了再回來(lái)補(bǔ)充
使用Spark Shuffle Service,需要在YARN集群里做如下操作
- 使用YARN profile構(gòu)建Spark铲敛。如果現(xiàn)在在使用預(yù)編譯的發(fā)布版則跳過(guò)此步
- 找到spark-<version>-yarn-shuffle.jar褐澎。如果是自己構(gòu)建這個(gè)包應(yīng)該在 $SPARK_HOME/common/network-yarn/target/scala-<version>目錄下。
如果使用的是發(fā)布版原探,這個(gè)包應(yīng)該在yarn目錄下 - 在集群的每個(gè)NodeManager上把這個(gè)包添加到環(huán)境變量里
- 集群的每個(gè)NodeManager上的yarn-site.xml中乱凿,把spark_shuffle設(shè)置為 yarn.nodemanager.aux-services的值顽素。然后設(shè)置org.apache.spark.network.yarn.YarnShuffleService替代yarn.nodemanager.aux-services.spark_shuffle.class
- 給NodeManager增加堆內(nèi)存咽弦,在etc/hadoop/yarn-env.sh中設(shè)置YARN_HEAPSIZE徒蟆。這個(gè)設(shè)置避免Shuffle過(guò)程中的內(nèi)存回收
- 重啟YARN集群中的所有NodeManager
當(dāng)Spark Shuffle Service在YARN集群跑起來(lái)后,可以使用這個(gè)配置項(xiàng)
spark.yarn.shuffle.stopOnFailure 型型,默認(rèn)是false段审。當(dāng)SparkShuffleService初始化失敗的時(shí)候是否關(guān)閉NodeManager。這個(gè)配置是避免當(dāng)機(jī)器上的SparkShuffleService不可用的時(shí)候闹蒜,任務(wù)被分配到了這臺(tái)機(jī)器上寺枉。