Spark是什么昨登?
Apache Spark 是專為大規(guī)模數(shù)據(jù)處理而設(shè)計(jì)的快速通用的計(jì)算引擎盏混,是一種開源的類Hadoop MapReduce的通用并行框架峰搪,擁有Hadoop MapReduce所具有的優(yōu)點(diǎn)愕难。
Spark不同于MapReduce的是嵌洼,Spark的Job中間輸出結(jié)果可以保存在內(nèi)存中,從而不再需要讀寫HDFS祝沸,因此Spark能更好地適用于數(shù)據(jù)挖掘與機(jī)器學(xué)習(xí)等需要迭代的MapReduce的算法矮烹。
Spark 主要有三個(gè)特點(diǎn)?:
首先,高級 API 剝離了對集群本身的關(guān)注罩锐,Spark 應(yīng)用開發(fā)者可以專注于應(yīng)用所要做的計(jì)算本身奉狈。
其次,Spark 很快涩惑,支持交互式計(jì)算和復(fù)雜算法仁期。
最后,Spark 是一個(gè)通用引擎竭恬,可用它來完成各種各樣的運(yùn)算跛蛋,包括 SQL 查詢、文本處理萍聊、機(jī)器學(xué)習(xí)等问芬,而在 Spark 出現(xiàn)之前,我們一般需要學(xué)習(xí)各種各樣的引擎來分別處理這些需求寿桨。
總結(jié)一下:從各種方向上(比如開發(fā)速度和運(yùn)行速度等)來看,Spark都優(yōu)于Hadoop MapReduce强戴;同時(shí)亭螟,Spark還提供大數(shù)據(jù)生態(tài)的一站式解決方案。因此骑歹,學(xué)會(huì)使用Spark刻不容緩预烙。
目錄
Spark生態(tài)圈
Spark運(yùn)行架構(gòu)
Spark運(yùn)行模式
Spark的Job執(zhí)行流程
Spark編程模型之RDD
Spark使用的簡單Demo
Spark生態(tài)圈
首先,我們先來看一下整個(gè)Spark的生態(tài)圈道媚,都有哪些功能扁掸。
下圖很好的說明了整個(gè)Spark的層級之間翘县,以及同級之間的關(guān)系。(注意谴分,此圖有些老锈麸,一些名稱已經(jīng)不再使用)
從下往上看,分別是:
數(shù)據(jù)層:Spark可以運(yùn)行在眾多底層的數(shù)據(jù)模型中牺蹄,比如HDFS忘伞、HBASE、Amazon s3等
資源調(diào)度層:這一層是Spark的四種運(yùn)行模式沙兰,包括一種本地模式local氓奈,和三種集群模式Standalone,Mesos鼎天,Yarn舀奶。
計(jì)算層:這一層是Spark的核心層,Spark Core斋射;其計(jì)算模型基于RDD(彈性分布式數(shù)據(jù)集)
應(yīng)用層:這一部分提供了基于Spark Core的高級應(yīng)用育勺,如用于交互式查詢的SparkSQL(即圖中的shark),用于流式處理的Spark Streaming绩鸣,用于機(jī)器學(xué)習(xí)的MLlib和用于圖計(jì)算的GraphX等怀大。
下圖展示的是目前的Spark的生態(tài)圈及組件。
Spark運(yùn)行架構(gòu)
凡是用于大數(shù)據(jù)處理的呀闻,幾乎都是主從模式(master/slave)化借,Spark也不例外。
Spark的主節(jié)點(diǎn)捡多,被稱之為Driver蓖康,其控制著整個(gè)Spark程序的應(yīng)用上下文:SparkContext。
Spark的從節(jié)點(diǎn)垒手,稱為Executor蒜焊,負(fù)責(zé)執(zhí)行具體的任務(wù)。
簡單解釋一下上圖:
1 首先Driver會(huì)創(chuàng)建一個(gè)SparkContext科贬,然后和集群資源的管理者Cluster Manager進(jìn)行通信泳梆,申請資源。
2 Cluster Manager會(huì)根據(jù)實(shí)際情況將合適的Worker節(jié)點(diǎn)分配給Spark榜掌,作為Executor使用优妙。
3 Driver和各Executor建立連接,生成DAG圖憎账,劃分Stage套硼,進(jìn)行Task調(diào)度;Executor則負(fù)責(zé)具體的Task執(zhí)行胞皱。
Spark運(yùn)行模式
Spark的運(yùn)行模式往粗了說邪意,就只有兩種:用于測試和學(xué)習(xí)的本地模式九妈,和用于實(shí)際生產(chǎn)的集群模式。細(xì)分一下雾鬼,集群模式主要分為Standalone萌朱,Spark on Memos,Spark on Yarn三種方式呆贿。當(dāng)然還有更細(xì)的劃分方式嚷兔,不過我們此處就不討論了,所以我們主要介紹下面的四種方式做入。
本地模式
一般是指“Local[N]”模式冒晰,其使用N個(gè)線程來進(jìn)行主從模擬。不需要進(jìn)行額外的參數(shù)配置竟块,安裝好Spark之后壶运,默認(rèn)啟動(dòng)的就是這種模式。
其操作全為單機(jī)完成浪秘,主要用于學(xué)習(xí)和功能測試蒋情。
Standalone
這里需要構(gòu)建一個(gè)由Master+Slave構(gòu)成的Spark集群,Spark運(yùn)行在集群中耸携。
這種模式是指利用Spark自己原生的master作為Cluster Manager來管理集群資源棵癣。這里需要注意的是,master并不是driver夺衍。master只擔(dān)任資源管理調(diào)度等方面的工作狈谊,具體的Task調(diào)度還是由driver完成。
Spark on Memos
Spark客戶端直接連接Mesos沟沙,不需要額外構(gòu)建Spark集群河劝,這種模式利用Memos的調(diào)度機(jī)制來管理集群。
Spark on Yarn
Spark客戶端直接連接Yarn矛紫,不需要額外構(gòu)建Spark集群赎瞎,這種模式是指利用Yarn的調(diào)度機(jī)制來管理集群,即上圖中的spark運(yùn)行架構(gòu)中的Cluster Manager為Resource Manager颊咬。
需要補(bǔ)充的一點(diǎn)是务甥,幾種集群模式中,都有兩種細(xì)分的方式喳篇,這里以Standalone為例缓呛。
Standalone Client模式(集群)
該模式運(yùn)行與集群之上,使用這種模式的時(shí)候杭隙,Master進(jìn)程做為cluster manager,SparkSubmit做為Client端和運(yùn)行driver程序因妙;Worker進(jìn)程用來作為Executor痰憎。
Standalone Cluster模式(集群)
該模式也是運(yùn)行于集群之上票髓,使用這種模式的時(shí)候,Client端的SparkSubmit進(jìn)程會(huì)在提交任務(wù)之后退出铣耘,Client不再負(fù)責(zé)運(yùn)行driver程序洽沟;Master會(huì)在集群中選擇一個(gè)Worker進(jìn)程生成一個(gè)子進(jìn)程DriverWrapper來啟動(dòng)driver程序;同時(shí)因?yàn)镈riverWrapper 進(jìn)程會(huì)占用Worker進(jìn)程的一個(gè)core蜗细,所以同樣的資源下配置下裆操,會(huì)比Standalone Client模式,少用1個(gè)core來參與計(jì)算炉媒。
總結(jié)一下:Client模式中踪区,Client提交任務(wù)之后,會(huì)作為Spark程序的driver吊骤,仍然和集群保持連接缎岗;而Cluster模式中,Client提交任務(wù)之后就退出白粉,由集群中的某個(gè)節(jié)點(diǎn)擔(dān)任driver传泊,也可以簡單理解為后臺模式。
Spark執(zhí)行流程(Job的執(zhí)行流程)
整個(gè)Spark執(zhí)行任務(wù)鸭巴,可以分為以下四個(gè)部分:
Driver端:
1 生成邏輯查詢計(jì)劃
2 生成物理查詢計(jì)劃
3 任務(wù)調(diào)度
Executor端
4 任務(wù)執(zhí)行
整個(gè)流程的簡圖可以參照下圖:
如果對上面的流程有疑惑的話眷细,可以這么考慮:
Driver端:
1 生成邏輯查詢計(jì)劃:這一步主要是根據(jù)我們對RDD的操作,比如map鹃祖,join溪椎,reduce等操作,來設(shè)定RDD的查詢依賴關(guān)系惯豆。
2 生成物理查詢計(jì)劃:根據(jù)上一步的邏輯圖和數(shù)據(jù)實(shí)際分布的情況池磁,生成整個(gè)任務(wù)實(shí)際執(zhí)行的調(diào)度圖(DAG圖)。
3 任務(wù)調(diào)度:根據(jù)第二步生成的DAG圖楷兽,進(jìn)行具體的任務(wù)調(diào)度地熄。
Executor端
4 任務(wù)執(zhí)行:Executor執(zhí)行具體的任務(wù)
詳細(xì)的Job執(zhí)行的流程圖,如下:
Spark編程模型之RDD(resilient distributed dataset)
RDD定義
RDD芯杀,彈性分布式數(shù)據(jù)集端考,是Spark中的數(shù)據(jù)抽象模型和編程模型,本質(zhì)上是一種抽象的特殊集合 揭厚。
RDD的特點(diǎn)是支持多種數(shù)據(jù)來源?? 有容錯(cuò)機(jī)制?? 可以被緩存?? 支持并行操作等却特。
在邏輯上,一個(gè)RDD代表一個(gè)數(shù)據(jù)集筛圆。而在物理上裂明,同一個(gè)RDD里的數(shù)據(jù)可能分布在不同的節(jié)點(diǎn)。
下圖表示一個(gè)RDD在物理上跨節(jié)點(diǎn)的分布情況太援。
RDD創(chuàng)建
#RDD主要有三種方式創(chuàng)建
1 通過內(nèi)存中的數(shù)據(jù)創(chuàng)建(比如內(nèi)存中的數(shù)組闽晦,適合學(xué)習(xí)測試使用)
val seq=Seq(1,2,3)
val rdd=sc.makeRDD(seq)
2 通過外部數(shù)據(jù)集創(chuàng)建(如HDFS數(shù)據(jù)集扳碍,一般用在生產(chǎn)環(huán)境)
val rdd=sc.textFile("test.txt")
3 通過其他RDD轉(zhuǎn)換而來(RDD transformation)
val childRdd=rdd.map(func)
RDD操作
RDD的操作分為兩種:Transformation(轉(zhuǎn)換)操作和Action(執(zhí)行)操作。其中仙蛉,轉(zhuǎn)換操作會(huì)生成一個(gè)新的RDD笋敞,但這種操作是惰性的,并不會(huì)立即執(zhí)行荠瘪,而是生成了RDD間的相互依賴關(guān)系夯巷;執(zhí)行操作一般是“寫”操作,“寫”到driver的collect()哀墓、take()和寫到文件的save()等趁餐,或者立刻需要返回結(jié)果的count()等函數(shù);執(zhí)行操作都是立即執(zhí)行的麸祷。
Transformation
1 將一個(gè)RDD轉(zhuǎn)化成一個(gè)新的RDD
2 保存RDD間的依賴關(guān)系澎怒,生成DAG圖
3 惰性操作,不會(huì)立刻執(zhí)行
Action
1 觸發(fā)任務(wù)的執(zhí)行
RDD依賴關(guān)系
上面已經(jīng)說到阶牍,RDD可以由RDD轉(zhuǎn)換而來喷面,這樣就形成了RDD之間的相互依賴關(guān)系。根據(jù)RDD在實(shí)際執(zhí)行中的表現(xiàn)走孽,可以將RDD間的依賴關(guān)系分為以下兩種:
窄依賴:每個(gè)父RDD的一個(gè)Partition最多被子RDD的一個(gè)Partition所使用
寬依賴:每個(gè)父RDD的一個(gè)Partition會(huì)被多個(gè)子RDD的Partition所使用
簡單來說惧辈,窄依賴就是父子的一對一或者多對一關(guān)系,寬依賴就是父子的一對多關(guān)系磕瓷。Job執(zhí)行時(shí)盒齿,當(dāng)窄依賴失敗時(shí),只需要重算對應(yīng)的父RDD就可以了困食;而當(dāng)寬依賴失敗的時(shí)候边翁,需要重算所有對應(yīng)的父RDD,而重算的父RDD中硕盹,會(huì)有一些是無效的符匾;同時(shí),寬依賴一般會(huì)跨節(jié)點(diǎn)瘩例,產(chǎn)生大量的shuffle過程啊胶,所以要盡量減少寬依賴。
RDD的寬依賴:stage的劃分
那么垛贤,RDD的寬窄依賴有什么用呢焰坪?上面也說過,知道什么是寬依賴聘惦,并且知道寬依賴是性能瓶頸某饰,有助于我們優(yōu)化程序的執(zhí)行。
其次,RDD的寬依賴露乏,也是stage的劃分依據(jù)碧浊,如下圖所示:
Spark使用的簡單Demo
文集
文章