Spark是什么?
Spark是基于內(nèi)存計(jì)算的大數(shù)據(jù)并行計(jì)算框架.Spark基于內(nèi)存計(jì)算,提高了在大數(shù)據(jù)環(huán)境下數(shù)據(jù)處理的實(shí)時(shí)性,同時(shí)保證了高容錯(cuò)性和高可伸縮性,允許用戶(hù)將Spark部署在大量的廉價(jià)硬件之上,形成集群
Spark誕生于加州大學(xué)伯利克分校AMPLab
AMPLab開(kāi)發(fā)以Spark為核心的BDAS時(shí)提出的目標(biāo)是:one stack to rule them all,也就是說(shuō)在一套軟件棧內(nèi)完成各種大數(shù)據(jù)分析任務(wù).
Spark是MapReduce的替代方案,而且兼容HDFS、Hive等分布式存儲(chǔ)層,可融入
Hadoop的生態(tài)系統(tǒng),以彌補(bǔ)缺失MapReduce的不足
Spark相比Hadoop MapReduce的優(yōu)勢(shì)如下:
(1)中間結(jié)果輸出
基于MapReduce的計(jì)算引擎通常會(huì)將中間結(jié)果輸出到磁盤(pán)上,進(jìn)行存儲(chǔ)和容錯(cuò)。出于
任務(wù)管道承接的考慮,當(dāng)一些查詢(xún)翻譯到MapReduce任務(wù)時(shí),往往會(huì)產(chǎn)生多個(gè)Stage,而
這些串聯(lián)的Stage又依賴(lài)于底層文件系統(tǒng)(如HDFS)來(lái)存儲(chǔ)每一個(gè)Stage的輸出結(jié)果。
Spark將執(zhí)行模型抽象為通用的有向無(wú)環(huán)圖執(zhí)行計(jì)劃(DAG),這可以將多Stage的任
務(wù)串聯(lián)或者并行執(zhí)行,而無(wú)須將Stage中間結(jié)果輸出到HDFS中。類(lèi)似的引擎包括Dr yad、
Tez。
(2)數(shù)據(jù)格式和內(nèi)存布局
Spark抽象出分布式內(nèi)存存儲(chǔ)結(jié)構(gòu)彈性分布式數(shù)據(jù)集RDD,進(jìn)行數(shù)據(jù)的存儲(chǔ)。RDD能支持粗粒度寫(xiě)操作,但對(duì)于讀取操作,RDD可以精確到每條記錄,這使得RDD可以用來(lái)作為分布式索引
Spark的特性是能夠控制數(shù)據(jù)在不同節(jié)點(diǎn)上的分區(qū),用戶(hù)可以自定義分區(qū)策略,如Hash分區(qū)等.Shark和Spark SQL在Spark的基礎(chǔ)上實(shí)現(xiàn)了列存儲(chǔ)和列存儲(chǔ)壓縮
(3)執(zhí)行策略
Spark任務(wù)在shuffle中不是所有情景都需要排序,所以支持基于Hash的分布式聚合,調(diào)度中采用更為通用的任務(wù)執(zhí)行計(jì)劃圖(DAG),每一輪次的輸出結(jié)果在內(nèi)存緩存
(4)任務(wù)調(diào)度的開(kāi)銷(xiāo)
傳統(tǒng)的MapReduce系統(tǒng),是為了運(yùn)行長(zhǎng)達(dá)數(shù)小時(shí)的批量作業(yè)而設(shè)計(jì)的,在某些極端的情況下,提交一個(gè)任務(wù)的延遲非常高
Spark采用了事件驅(qū)動(dòng)的類(lèi)庫(kù)AKKA來(lái)啟動(dòng)任務(wù),通過(guò)線程池復(fù)用線程來(lái)避免進(jìn)程或線程啟動(dòng)和切換開(kāi)銷(xiāo)
Spark生態(tài)系統(tǒng)BDAS(Berkeley Data Analytics Stack)
目前,Spark已經(jīng)發(fā)展成為包含眾多子項(xiàng)目的大數(shù)據(jù)計(jì)算平臺(tái)。伯克利將Spark的整個(gè)
生態(tài)系統(tǒng)稱(chēng)為伯克利數(shù)據(jù)分析棧(BDAS)。其核心框架是Spark,同時(shí)BDAS涵蓋支持結(jié)
構(gòu)化數(shù)據(jù)SQL查詢(xún)與分析的查詢(xún)引擎Spark SQL和Shark,提供機(jī)器學(xué)習(xí)功能的系統(tǒng)
MLbase及底層的分布式機(jī)器學(xué)習(xí)庫(kù)MLlib、并行圖計(jì)算框架GraphX、流計(jì)算框架Spark
Streaming、采樣近似計(jì)算查詢(xún)引擎BlinkDB、內(nèi)存分布式文件系統(tǒng)Tachyon、資源管理框
架Mesos等子項(xiàng)目。這些子項(xiàng)目在Spark上層提供了更高層、更豐富的計(jì)算范式。
圖1-1為BDAS的項(xiàng)目結(jié)構(gòu)圖。

圖1-1 伯克利數(shù)據(jù)分析棧(BDAS)項(xiàng)目結(jié)構(gòu)圖
下面對(duì)BDAS的各個(gè)子項(xiàng)目進(jìn)行更詳細(xì)的介紹。
(1)Spark
Spark是整個(gè)BDAS的核心組件,是一個(gè)大數(shù)據(jù)分布式編程框架,不僅實(shí)現(xiàn)了MapReduce的算子map函數(shù)和reduce函數(shù)及計(jì)算模型,還提供更為豐富的算子,如filter、join、groupByKey等.其底層采用Scala這種函數(shù)式語(yǔ)言書(shū)寫(xiě)而成,并且所提供的API深度借鑒Scala函數(shù)式的編程思想,提供與Scala類(lèi)似的編程接口。
圖1-2為Spark的處理流程(主要對(duì)象為RDD)。

Spark將數(shù)據(jù)在分布式環(huán)境下分區(qū),然后將作業(yè)轉(zhuǎn)化為有向無(wú)環(huán)圖(DAG),并分階段進(jìn)行DAG的調(diào)度和任務(wù)的分布式并行處理。
(2)Shark
Shark是構(gòu)建在Spark和Hive基礎(chǔ)之上的數(shù)據(jù)倉(cāng)庫(kù)。Shark底層復(fù)用Hive的解析器、優(yōu)化
器以及元數(shù)據(jù)存儲(chǔ)和序列化接口。Shark會(huì)將Hive QL編譯轉(zhuǎn)化為一組Spark任務(wù),進(jìn)行分布式運(yùn)算。
(3)Spark SQL
Spark SQL提供在大數(shù)據(jù)上的SQL查詢(xún)功能,類(lèi)似于Shark在整個(gè)生態(tài)系統(tǒng)的角色,它們可以統(tǒng)稱(chēng)為SQL on Spark。Spark SQL使用Catalyst做查詢(xún)解析和優(yōu)化器,并在底層使用Spark作為執(zhí)行引擎實(shí)現(xiàn)SQL的Operator
(4)Spark Streaming
Spark Streaming通過(guò)將流數(shù)據(jù)按指定時(shí)間片累積為RDD,然后將每個(gè)RDD進(jìn)行批處理,進(jìn)而實(shí)現(xiàn)大規(guī)模的流數(shù)據(jù)處理。其吞吐量能夠超越現(xiàn)有主流流處理框架Storm,并提供豐富的API用于流數(shù)據(jù)計(jì)算。
(5)GraphX
GraphX基于BSP模型,在Spark之上封裝類(lèi)似Pregel的接口,進(jìn)行大規(guī)模同步全局的圖計(jì)算,尤其是當(dāng)用戶(hù)進(jìn)行多輪迭代時(shí),基于Spark內(nèi)存計(jì)算的優(yōu)勢(shì)尤為明顯
(6)Tachyon
Tachyon是一個(gè)分布式內(nèi)存文件系統(tǒng),可以理解為內(nèi)存中的HDFS。為了提供更高的性能,將數(shù)據(jù)存儲(chǔ)剝離Java Heap
(7)Mesos
Mesos是一個(gè)資源管理框架,提供類(lèi)似于YARN的功能。用戶(hù)可以在其中插件式地運(yùn)行Spark、MapReduce、Tez等計(jì)算框架的任務(wù)。Mesos會(huì)對(duì)資源和任務(wù)進(jìn)行隔離,并實(shí)現(xiàn)高效的資源任務(wù)調(diào)度。
(8)BlinkDB
BlinkDB是一個(gè)用于在海量數(shù)據(jù)上進(jìn)行交互式SQL的近似查詢(xún)引擎。它允許用戶(hù)通過(guò)在查詢(xún)準(zhǔn)確性和查詢(xún)響應(yīng)時(shí)間之間做出權(quán)衡,完成近似查詢(xún)。其數(shù)據(jù)的精度被控制在允許的誤差范圍內(nèi)。為了達(dá)到這個(gè)目標(biāo),BlinkDB的核心思想是:通過(guò)一個(gè)自適應(yīng)優(yōu)化框架,隨著時(shí)間的推移,從原始數(shù)據(jù)建立并維護(hù)一組多維樣本;通過(guò)一個(gè)動(dòng)態(tài)樣本選擇策略,選擇一個(gè)適當(dāng)大小的示例,然后基于查詢(xún)的準(zhǔn)確性和響應(yīng)時(shí)間滿(mǎn)足用戶(hù)查詢(xún)需求。
Spark架構(gòu)
Spark是整個(gè)BDAS的核心。生態(tài)系統(tǒng)中的各個(gè)組件通過(guò)Spark來(lái)實(shí)現(xiàn)對(duì)分布式并行任務(wù)處理的程序支持
Spark架構(gòu)采用了分布式計(jì)算中的Master-Slave模型。Master是對(duì)應(yīng)集群中的含有Master進(jìn)程的節(jié)點(diǎn),Slave是集群中含有Worker進(jìn)程的節(jié)點(diǎn)。Master作為整個(gè)集群的控制器,負(fù)責(zé)整個(gè)集群的正常運(yùn)行;Worker相當(dāng)于是計(jì)算節(jié)點(diǎn),接收主節(jié)點(diǎn)命令與進(jìn)行狀態(tài)匯報(bào);Executor負(fù)責(zé)任務(wù)的執(zhí)行;Client作為用戶(hù)的客戶(hù)端負(fù)責(zé)提交應(yīng)用,Driver負(fù)責(zé)控制一個(gè)應(yīng)用的執(zhí)行,如圖1-4所示。

Spark集群部署后,需要在主節(jié)點(diǎn)和從節(jié)點(diǎn)分別啟動(dòng)Master進(jìn)程和Worker進(jìn)程,對(duì)整個(gè)集群進(jìn)行控制。在一個(gè)Spark應(yīng)用的執(zhí)行過(guò)程中,Driver和Worker是兩個(gè)重要角色。Driver程序是應(yīng)用邏輯執(zhí)行的起點(diǎn),負(fù)責(zé)作業(yè)的調(diào)度,即Task任務(wù)的分發(fā),而多個(gè)Worker用來(lái)管理計(jì)算節(jié)點(diǎn)和創(chuàng)建Executor并行處理任務(wù)。在執(zhí)行階段,Driver會(huì)將Task和Task所依賴(lài)的file和jar序列化后傳遞給對(duì)應(yīng)的Worker機(jī)器,同時(shí)Executor對(duì)相應(yīng)數(shù)據(jù)分區(qū)的任務(wù)進(jìn)行處理。
下面詳細(xì)介紹Spark的架構(gòu)中的基本組件。
·ClusterManager:在Standalone模式中即為Master(主節(jié)點(diǎn)),控制整個(gè)集群,監(jiān)控Worker。在YARN模式中為資源管理器。
Worker:從節(jié)點(diǎn),負(fù)責(zé)控制計(jì)算節(jié)點(diǎn),啟動(dòng)Executor或Driver。在YARN模式中為NodeManager,負(fù)責(zé)計(jì)算節(jié)點(diǎn)的控制
·Driver:運(yùn)行Application的main()函數(shù)并創(chuàng)建SparkContext。
·Executor:執(zhí)行器,在worker node上執(zhí)行任務(wù)的組件、用于啟動(dòng)線程池運(yùn)行任務(wù)。每個(gè)Application擁有獨(dú)立的一組Executors。
·SparkContext:整個(gè)應(yīng)用的上下文,控制應(yīng)用的生命周期
·RDD:Spark的基本計(jì)算單元,一組RDD可形成執(zhí)行的有向無(wú)環(huán)圖RDD Graph
·DAG Scheduler:根據(jù)作業(yè)(Job)構(gòu)建基于Stage的DAG,并提交Stage給
TaskScheduler。
·TaskScheduler:將任務(wù)(Task)分發(fā)給Executor執(zhí)行。
·TaskScheduler:將任務(wù)(Task)分發(fā)給Executor執(zhí)行。
·SparkEnv:線程級(jí)別的上下文,存儲(chǔ)運(yùn)行時(shí)的重要組件的引用。
SparkEnv內(nèi)創(chuàng)建并包含如下一些重要組件的引用。
·MapOutPutTracker:負(fù)責(zé)Shuffle元信息的存儲(chǔ)。
·BroadcastManager:負(fù)責(zé)廣播變量的控制與元信息的存儲(chǔ)。
·BlockManager:負(fù)責(zé)存儲(chǔ)管理、創(chuàng)建和查找塊。
·MetricsSystem:監(jiān)控運(yùn)行時(shí)性能指標(biāo)信息。
·SparkConf:負(fù)責(zé)存儲(chǔ)配置信息。
Spark的整體流程為:Client提交應(yīng)用,Master找到一個(gè)Worker啟動(dòng)Driver,Driver向Master或者資源管理器申請(qǐng)資源,之后將應(yīng)用轉(zhuǎn)化為RDD Graph,再由DAGScheduler將RDD Graph轉(zhuǎn)化為Stage的有向無(wú)環(huán)圖提交給TaskScheduler,由TaskScheduler提交任務(wù)給Executor執(zhí)行。在任務(wù)執(zhí)行的過(guò)程中,其他組件協(xié)同工作,確保整個(gè)應(yīng)用順利執(zhí)行。
Spark運(yùn)行邏輯
如圖1-5所示,在Spark應(yīng)用中,整個(gè)執(zhí)行流程在邏輯上會(huì)形成有向無(wú)環(huán)圖(DAG)。Action算子觸發(fā)之后,將所有累積的算子形成一個(gè)有向無(wú)環(huán)圖,然后由調(diào)度器調(diào)度該圖上的任務(wù)進(jìn)行運(yùn)算。Spark的調(diào)度方式與MapReduce有所不同。Spark根據(jù)RDD之間不同的依賴(lài)關(guān)系切分形成不同的階段(Stage),一個(gè)階段包含一系列函數(shù)執(zhí)行流水線。圖中的A、B、C、D、E、F分別代表不同的RDD,RDD內(nèi)的方框代表分區(qū)。數(shù)據(jù)從HDFS輸入
Spark,形成RDD A和RDD C,RDD C上執(zhí)行map操作,轉(zhuǎn)換為RDD D,RDD B和RDDE執(zhí)行join操作,轉(zhuǎn)換為F,而在B和E連接轉(zhuǎn)化為F的過(guò)程中又會(huì)執(zhí)行Shuffle,最后RDD F通過(guò)函數(shù)saveAsSequenceFile輸出并保存到HDFS中。

Spark分布式架構(gòu)與單機(jī)多核架構(gòu)的異同
1)在單機(jī)多核環(huán)境下,多CPU共享內(nèi)存和磁盤(pán)。當(dāng)系統(tǒng)所需的計(jì)算和存儲(chǔ)資源不夠,需要擴(kuò)展CPU和存儲(chǔ)時(shí),單機(jī)多核系統(tǒng)顯得力不從心。
2)大規(guī)模分布式并行處理系統(tǒng)是由許多松耦合的處理單元組成的,要注意的是,這里指的是處理單元而非處理器。每個(gè)單元內(nèi)的CPU都有自己私有的資源,如總線、內(nèi)存、硬盤(pán)等。這種結(jié)構(gòu)最大的特點(diǎn)在于不共享資源。在不共享資源(Share Nothing)的分布式架構(gòu)下,節(jié)點(diǎn)可以實(shí)現(xiàn)無(wú)限擴(kuò)展,即計(jì)算能力和存儲(chǔ)的擴(kuò)展性可以成倍增長(zhǎng)。
在分布式運(yùn)算下,數(shù)據(jù)盡量本地運(yùn)算,減少網(wǎng)絡(luò)I/O開(kāi)銷(xiāo)。由于大規(guī)模分布式系統(tǒng)要在不同處理單元之間傳送信息,在網(wǎng)絡(luò)傳輸少時(shí),系統(tǒng)可以充分發(fā)揮資源的優(yōu)勢(shì),達(dá)到高效率。也就是說(shuō),如果操作相互之間沒(méi)有什么關(guān)系,處理單元之間需要進(jìn)行的通信比較少,則采用分布式系統(tǒng)更好。因此,分布式系統(tǒng)在決策支持(DSS)和數(shù)據(jù)挖掘(DataMining)方面具有優(yōu)勢(shì)。