spark任务shell运行_了解Spark 应用的一生
Spark從被創(chuàng)造至今已經(jīng)成為了大數(shù)據(jù)計(jì)算引擎中不可或缺的一環(huán),雖然Spark非常的優(yōu)秀但相比于其他的開(kāi)源框架依然有著比較高的學(xué)習(xí)門(mén)檻,希望能夠通過(guò)一種有結(jié)構(gòu)性的,簡(jiǎn)單直接的方式,為Spark的初學(xué)者入門(mén)。
核心概念講解
Spark 應(yīng)用的架構(gòu)
Driver
Driver 是整體Spark Application的架構(gòu)中最重要的一個(gè)進(jìn)程。為了便于理解,我們可以將Driver理解為是一個(gè)建筑工地的包工頭,他了解整個(gè)項(xiàng)目的實(shí)施步驟與實(shí)施內(nèi)容。它主要負(fù)責(zé)分派任務(wù),監(jiān)督任務(wù)的進(jìn)程,同時(shí)還需要時(shí)刻關(guān)心項(xiàng)目需要的建筑材料是否充分。
Executor
Executor 是除了Drvier以外負(fù)責(zé)執(zhí)行任務(wù)的進(jìn)程。這些任務(wù)都由Driver來(lái)指定。Executor可以被理解為包工頭下面的工人,他們不需要太多思考,而是專(zhuān)注于完成指定的任務(wù)。他們只需要接受任務(wù),執(zhí)行,并將執(zhí)行后的狀態(tài)與結(jié)果返回即可。
Cluster Manager
Cluster Manager的概念比以上的概念稍微較難理解一些,Cluster Manager搭建了Spark Application與具體的物理機(jī)器的橋梁。如果將Spark Application理解為一個(gè)施工項(xiàng)目的話(huà),那么Cluster Mangager可以理解為是一個(gè)建筑材料管理者。一個(gè)施工項(xiàng)目的完成需要提供足夠的建材支持執(zhí)行,而當(dāng)需要這些資源的時(shí)候,便需要與Cluster Manager交流。當(dāng)然這只是為了便于理解而做的類(lèi)比。真正的Cluster Manager中也會(huì)有自己的結(jié)構(gòu),也是一個(gè)Master/Workor的結(jié)構(gòu)。這樣的結(jié)構(gòu)是為了更好的管理分布式的集群的物理機(jī)器。我們可以通過(guò)下圖對(duì)Cluster Mangager有一個(gè)了解。現(xiàn)在Spark支持Standalone, Mesos, Yarn 三種方式,K8s會(huì)在Spark3之后支持。
Spark 執(zhí)行模式
在理解了一個(gè)Spark Application里面的組成部分之后,我們來(lái)看看Spark Application能夠執(zhí)行的模式
Cluster Mode
Cluster Mode是Spark Application最常用的模式。在生產(chǎn)環(huán)境除非特殊原因都會(huì)采用Cluster的模式來(lái)執(zhí)行。在Cluster mode下,用戶(hù)提交一個(gè)Jar,pyton script或者R sciprt給Cluster Manager。之后Cluster Manager在某一個(gè)Workor節(jié)點(diǎn)上啟動(dòng)Driver的進(jìn)程。在Cluster Mode下,Cluster manager負(fù)責(zé)維持所有Spark應(yīng)用進(jìn)程。下圖便解釋了Cluster mode執(zhí)行時(shí)的狀態(tài)。Cluster Manager選取一個(gè)Workor節(jié)點(diǎn)跑Driver,之后再分配其他Worker跑其余的Executor。
Client Mode
Client Mode與Cluster Mode基本一致除了Driver進(jìn)程并非由Cluster Manager來(lái)管理,而是繼續(xù)跑在提交任務(wù)的機(jī)器上。這也就意味著,Driver進(jìn)程將由提交任務(wù)的客戶(hù)端來(lái)維持狀態(tài)。Cluster Manager只是負(fù)責(zé)維持Executor的狀態(tài)。這些維持Driver的節(jié)點(diǎn),也被叫做Edge Node或者gateway Machines。下圖便解釋了Client Mode的運(yùn)行機(jī)制。
Local Mode
Local Mode是一種為了測(cè)試與開(kāi)發(fā)Spark應(yīng)用而存在的模式。它與前兩種截然不同。Local模式在一臺(tái)物理機(jī)器上運(yùn)行,同時(shí)Executor與Driver也從進(jìn)程變?yōu)榫€(xiàn)程。在生產(chǎn)環(huán)境中幾乎沒(méi)有不會(huì)使用local 模式。
小結(jié)
我們不妨思考一下,Spark為什么會(huì)創(chuàng)建出三種不同的運(yùn)行模式。什么時(shí)候又會(huì)使用什么樣的模式。Cluster的模式適用于大部分應(yīng)用場(chǎng)景,可以將它理解為一種離線(xiàn)提交任務(wù)的方式。Client模式非常適合shell, notebook這一類(lèi)需要一直有一個(gè)主線(xiàn)程維持著的應(yīng)用。而Local模式基本只適合測(cè)試的場(chǎng)景。
Spark 應(yīng)用的執(zhí)行過(guò)程
了解了Spark系統(tǒng)的組成部分,我們來(lái)看一個(gè)在Cluster Mode下跑的Spark Application的過(guò)程。
第一步, 任務(wù)請(qǐng)求
我們一般通過(guò)Spark-submit來(lái)提交一個(gè)Spark 應(yīng)用,提交的時(shí)候需要提供已經(jīng)編譯好的Jar包或者是python script,等這取決于不同的語(yǔ)言而不同。
通過(guò)上圖可以看到,執(zhí)行這一步任務(wù)的進(jìn)程還是在你自己本地的機(jī)器上,它需要負(fù)責(zé)給Cluster Manager發(fā)送請(qǐng)求,表明需要的資源大小。我們現(xiàn)在假設(shè)我們有足夠的資源,因此Cluster Manager接受了我們的請(qǐng)求,并尋找了一個(gè)Worker Node將Driver跑起來(lái)。如果一切順利,那么此本地進(jìn)程就會(huì)結(jié)束退出。
以下是一個(gè)任務(wù)提交的示例
./bin/spark-submit --class <main-class> --master <master-url> --deploy-mode cluster --conf <key>=<value> ... # other options <application-jar> [application-arguments]第二步,任務(wù)啟動(dòng)
當(dāng)Driver進(jìn)程開(kāi)始之后,Driver會(huì)擁有一個(gè)SparkSession的對(duì)象。SparkSession定義了運(yùn)行這個(gè)Spark Application所需要的環(huán)境信息。這包含了用多少資源,與Cluster Manager的溝通方式等。這些大部分都是在Spark-submit的時(shí)候可以進(jìn)行設(shè)置的內(nèi)容。
在這個(gè)過(guò)程中,Driver通過(guò)SparkSession這個(gè)對(duì)象,向Cluster Manager請(qǐng)求資源并建立起這個(gè)任務(wù)需要的集群,這樣一個(gè)可以用于執(zhí)行Spark Application的集群便準(zhǔn)備好了。這里需要注意,當(dāng)Cluster Manager在分配了資源之后,它會(huì)將這些信息給到Driver,之后Driver便可以直接與這些Executor交流。之后除非有新的資源請(qǐng)求,不然就不用再找Cluster Manager了。
第三步,任務(wù)執(zhí)行
執(zhí)行階段我們之后會(huì)將其中涉及的概念與過(guò)程詳細(xì)展開(kāi)。現(xiàn)在我們只需要知道這時(shí)候Driver已經(jīng)掌握了足夠的信息來(lái)執(zhí)行應(yīng)用了。所以會(huì)開(kāi)始分配executor到不同的Worker node上去。
我們需要注意這時(shí)候整體的控制權(quán)都是Driver手里,這個(gè)時(shí)候Cluster Manager只需要維持著Driver進(jìn)程的狀態(tài)即可,Cluster Manager并不感知任務(wù)的具體內(nèi)容。
任務(wù)完成
Driver的退出便標(biāo)志著應(yīng)用的完成,Driver退出時(shí)的狀態(tài)也會(huì)同時(shí)傳給Cluster Manager。這時(shí)候Cluster Manager會(huì)負(fù)責(zé)將之前分配的資源回收,并將Driver返回的狀態(tài)返回。
Spark 應(yīng)用內(nèi)部的過(guò)程
接下來(lái)我們仔細(xì)看看Spark Application在執(zhí)行的階段內(nèi)部都在發(fā)生著什么。為了能夠清楚的講清楚其中的過(guò)程,我們需要先引入Spark Application中的一些新的概念。
Spark Session
在Spark應(yīng)用的一開(kāi)始便是獲取一個(gè)Spark Session.如果是使用Spark-Shell,或者Zepplion等工具,你可能沒(méi)有意識(shí)到這個(gè)Session已經(jīng)在你啟動(dòng)Shell的時(shí)候獲得了。由于Spark版本的不同,初始化Spark Session的方式也經(jīng)歷了很多的變化,由于我們旨在講明白Spark Application的內(nèi)部運(yùn)行流程,就不在Spark Session的方面進(jìn)行過(guò)多的描述。我們只需要了解我們需要獲取SparkSession,之后才能獲得不同的Context對(duì)象來(lái)進(jìn)行Spark Application的開(kāi)發(fā)。我們可以調(diào)用SparkSQL的服務(wù),也可以調(diào)用底層的RDD的服務(wù)。這些都由不同的業(yè)務(wù)需求而確定。
Logical Instructions
無(wú)論你使用什么語(yǔ)言進(jìn)行Spark Application的開(kāi)發(fā),最終都會(huì)轉(zhuǎn)化為一個(gè)Logical Instruction的計(jì)劃,然后再變?yōu)橐粋€(gè)物理執(zhí)行計(jì)劃。如果你想要更加直觀的了解執(zhí)行計(jì)劃,你可以打開(kāi)Spark的UI。這時(shí)候我們便需要繼續(xù)介紹一下Spark Job的組成了。
在介紹Spark的Job組成之前,我們需要再引入兩個(gè)概念,一個(gè)是transformation,一個(gè)是shuffle。這對(duì)應(yīng)著在Spark中兩種不同的數(shù)據(jù)變換邏輯。如果對(duì)Map-Reduce有了解的話(huà)那么就不難理解,Transformation可以理解為Mapper能夠完成的邏輯,而Shuffle就是需要Reducer才能完成的邏輯。我們之后會(huì)將為什么這兩類(lèi)運(yùn)算對(duì)于Spark的計(jì)劃來(lái)說(shuō)非常的重要。
Spark Job
Spark Job在Spark Application中對(duì)應(yīng)的就是一個(gè)Action的操作。這時(shí)又需要引入Spark的Lazy Evaluation的機(jī)制。Spark只有在需要獲取結(jié)果的時(shí)候才會(huì)進(jìn)行運(yùn)算,在這之前只會(huì)保留執(zhí)行的計(jì)劃而不會(huì)調(diào)用任何計(jì)算的邏輯。
一個(gè)Job是有很多的Stage組成的,而一個(gè)Stage會(huì)包含若干個(gè)Task。
Spark Stage
一個(gè)Stage可以理解為是一組能夠被并行執(zhí)行的Task的集合,一個(gè)Shuffle的操作對(duì)應(yīng)一個(gè)Stage。Spark之所以執(zhí)行的速度比Map-reduce要優(yōu)秀,就是因?yàn)樗軌蜃隽己玫膬?yōu)化,能夠合理的將一個(gè)計(jì)算任務(wù)進(jìn)行整合。舉個(gè)例子如果你的操作都是select, filter等,那么他們會(huì)被整合在一個(gè)Stage當(dāng)中去完成。而整合的極限便是如果你需要做不同的Shuffle的操作,比如Sort, Grouping。那么Spark便會(huì)分開(kāi)不同的Stage來(lái)執(zhí)行。
Spark Tasks
一個(gè)Task就是Spark執(zhí)行中的最小單元,它跑在一臺(tái)機(jī)器上。有多少的Task需要被執(zhí)行,是有多少的partition來(lái)決定的。這里不做過(guò)多的贅述。我們只要理解Task是最小的執(zhí)行單元便可以。
Spark為什么快如閃電
1. Pipelining
Pipeling是Spark Application中最具特色的部分,大部分select, filter的操作都會(huì)通過(guò)pipeling的方式放在一個(gè)Stage中執(zhí)行。在這樣的執(zhí)行中會(huì)盡量的使用內(nèi)存而非存儲(chǔ),也正是因?yàn)檫@樣的優(yōu)化使得Spark在執(zhí)行很多相同的任務(wù)中有著更好的表現(xiàn)。
2. Shuffle Persistence
當(dāng)Spark需要做一個(gè)Shuffle的作業(yè)時(shí),Spark會(huì)先將輸入落盤(pán)。這樣的選擇不僅是為了以后做shuffle時(shí)的方便,同時(shí)它還帶來(lái)了一個(gè)額外的好處,便是因?yàn)閟huffle之前的內(nèi)容已經(jīng)落盤(pán),所以如果重新執(zhí)行這個(gè)任務(wù)的話(huà),已經(jīng)落盤(pán)的部分會(huì)自動(dòng)的跳過(guò)。
總結(jié)
我們分別講解了Spark集群的架構(gòu),一個(gè)Spark Application如何利用分布式的架構(gòu)執(zhí)行,以及在執(zhí)行的過(guò)程中Spark是如何處理內(nèi)部的應(yīng)用的。略顯粗淺,但基本涵蓋了Spark 應(yīng)用的方方面面。可以算是Spark應(yīng)用理解的啟蒙讀物吧。
Reference
[Spark 權(quán)威指南]
總結(jié)
以上是生活随笔為你收集整理的spark任务shell运行_了解Spark 应用的一生的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 前段react技术架构图_基于 Reac
- 下一篇: 征信可以修复吗 简单给大家聊一聊