您好,登錄后才能下訂單哦!
本篇文章給大家分享的是有關(guān)Spark原理的實(shí)例分析,小編覺(jué)得挺實(shí)用的,因此分享給大家學(xué)習(xí),希望大家閱讀完這篇文章后可以有所收獲,話(huà)不多說(shuō),跟著小編一起來(lái)看看吧。
Hadoop存在缺陷:
基于磁盤(pán),無(wú)論是MapReduce還是YARN都是將數(shù)據(jù)從磁盤(pán)中加載出來(lái),經(jīng)過(guò)DAG,然后重新寫(xiě)回到磁盤(pán)中
計(jì)算過(guò)程的中間數(shù)據(jù)又需要寫(xiě)入到HDFS的臨時(shí)文件
這些都使得Hadoop在大數(shù)據(jù)運(yùn)算上表現(xiàn)太“慢”,Spark應(yīng)運(yùn)而生。
Spark的架構(gòu)設(shè)計(jì):
ClusterManager負(fù)責(zé)分配資源,有點(diǎn)像YARN中ResourceManager那個(gè)角色,大管家握有所有的干活的資源,屬于乙方的總包。
WorkerNode是可以干活的節(jié)點(diǎn),聽(tīng)大管家ClusterManager差遣,是真正有資源干活的主。
Executor是在WorkerNode上起的一個(gè)進(jìn)程,相當(dāng)于一個(gè)包工頭,負(fù)責(zé)準(zhǔn)備Task環(huán)境和執(zhí)行Task,負(fù)責(zé)內(nèi)存和磁盤(pán)的使用。
Task是施工項(xiàng)目里的每一個(gè)具體的任務(wù)。
Driver是統(tǒng)管Task的產(chǎn)生與發(fā)送給Executor的,是甲方的司令員。
SparkContext是與ClusterManager打交道的,負(fù)責(zé)給錢(qián)申請(qǐng)資源的,是甲方的接口人。
整個(gè)互動(dòng)流程是這樣的:
1 甲方來(lái)了個(gè)項(xiàng)目,創(chuàng)建了SparkContext,SparkContext去找ClusterManager申請(qǐng)資源同時(shí)給出報(bào)價(jià),需要多少CPU和內(nèi)存等資源。ClusterManager去找WorkerNode并啟動(dòng)Excutor,并介紹Excutor給Driver認(rèn)識(shí)。
2 Driver根據(jù)施工圖拆分一批批的Task,將Task送給Executor去執(zhí)行。
3 Executor接收到Task后準(zhǔn)備Task運(yùn)行時(shí)依賴(lài)并執(zhí)行,并將執(zhí)行結(jié)果返回給Driver
4 Driver會(huì)根據(jù)返回回來(lái)的Task狀態(tài)不斷的指揮下一步工作,直到所有Task執(zhí)行結(jié)束。
再看下圖加深下理解:
核心部分是RDD相關(guān)的,就是我們前面介紹的任務(wù)調(diào)度的架構(gòu),后面會(huì)做更加詳細(xì)的說(shuō)明。
SparkStreaming:
基于SparkCore實(shí)現(xiàn)的可擴(kuò)展、高吞吐、高可靠性的實(shí)時(shí)數(shù)據(jù)流處理。支持從Kafka、Flume等數(shù)據(jù)源處理后存儲(chǔ)到HDFS、DataBase、Dashboard中。
MLlib:
關(guān)于機(jī)器學(xué)習(xí)的實(shí)現(xiàn)庫(kù),關(guān)于機(jī)器學(xué)習(xí)還是希望花點(diǎn)時(shí)間去系統(tǒng)的學(xué)習(xí)下各種算法,這里有一套基于Python的ML相關(guān)的博客教材http://blog.csdn.net/yejingtao703/article/category/7365067。
SparkSQL:
Spark提供的sql形式的對(duì)接Hive、JDBC、HBase等各種數(shù)據(jù)渠道的API,用Java開(kāi)發(fā)人員的思想來(lái)講就是面向接口、解耦合,ORMapping、Spring Cloud Stream等都是類(lèi)似的思想。
GraphX:
關(guān)于圖和圖并行計(jì)算的API,我還沒(méi)有用到過(guò)。
RDD(Resilient Distributed Datasets) 彈性分布式數(shù)據(jù)集
RDD支持兩種操作:轉(zhuǎn)換(transiformation)和動(dòng)作(action)
轉(zhuǎn)換就是將現(xiàn)有的數(shù)據(jù)集創(chuàng)建出新的數(shù)據(jù)集,像Map;動(dòng)作就是對(duì)數(shù)據(jù)集進(jìn)行計(jì)算并將結(jié)果返回給Driver,像Reduce。
RDD中轉(zhuǎn)換是惰性的,只有當(dāng)動(dòng)作出現(xiàn)時(shí)才會(huì)做真正運(yùn)行。這樣設(shè)計(jì)可以讓Spark更見(jiàn)有效的運(yùn)行,因?yàn)槲覀冎恍枰褎?dòng)作要的結(jié)果送給Driver就可以了而不是整個(gè)巨大的中間數(shù)據(jù)集。
緩存技術(shù)(不僅限內(nèi)存,還可以是磁盤(pán)、分布式組件等)是Spark構(gòu)建迭代式算法和快速交互式查詢(xún)的關(guān)鍵,當(dāng)持久化一個(gè)RDD后每個(gè)節(jié)點(diǎn)都會(huì)把計(jì)算分片結(jié)果保存在緩存中,并對(duì)此數(shù)據(jù)集進(jìn)行的其它動(dòng)作(action)中重用,這就會(huì)使后續(xù)的動(dòng)作(action)變得跟迅速(經(jīng)驗(yàn)值10倍)。例如RDD0àRDD1àRDD2,執(zhí)行結(jié)束后RDD1和RDD2的結(jié)果已經(jīng)在內(nèi)存中了,此時(shí)如果又來(lái)RDD0àRDD1àRDD3,就可以只計(jì)算最后一步了。
RDD之間的寬依賴(lài)和窄依賴(lài):
窄依賴(lài):父RDD的每個(gè)Partition只被子RDD的一個(gè)Partition使用。
寬依賴(lài):父RDD的每個(gè)Partition會(huì)被子RDD的多個(gè)Partition使用。
寬和窄可以理解為褲腰帶,褲腰帶扎的緊下半身管的嚴(yán)所以只有一個(gè)兒子;褲腰帶幫的比較寬松下半身管的不禁會(huì)搞出一堆私生子,這樣就記住了。
對(duì)于窄依賴(lài)的RDD,可以用一個(gè)計(jì)算單元來(lái)處理父子partition的,并且這些Partition相互獨(dú)立可以并行執(zhí)行;對(duì)于寬依賴(lài)完全相反。
在故障回復(fù)時(shí)窄依賴(lài)表現(xiàn)的效率更高,兒子壞了可以通過(guò)重算爹來(lái)得到兒子,反正就這一個(gè)兒子當(dāng)?shù)幕謴?fù)效率就是100%。但是對(duì)于寬依賴(lài)效率就很低了,如下圖:
用戶(hù)編排的代碼由一個(gè)個(gè)的RDD Objects組成,DAGScheduler負(fù)責(zé)根據(jù)RDD的寬依賴(lài)拆分DAG為一個(gè)個(gè)的Stage,買(mǎi)個(gè)Stage包含一組邏輯完全相同的可以并發(fā)執(zhí)行的Task。TaskScheduler負(fù)責(zé)將Task推送給從ClusterManager那里獲取到的Worker啟動(dòng)的Executor。
DAGScheduler(統(tǒng)一化的,Spark說(shuō)了算):
詳細(xì)的案例分析下如何進(jìn)行Stage劃分,請(qǐng)看下圖
Worker部分采用Master/Slaver模式,Master是整個(gè)系統(tǒng)的核心部件所以用ZooKeeper做高可用性加固,Slaver真正創(chuàng)建Executor執(zhí)行Task并將自己的物理計(jì)算資源匯報(bào)給Master,Master負(fù)責(zé)將slavers的資源按照策略分配給Framework。
Mesos資源調(diào)度分為粗粒度和細(xì)粒度兩種方式:
粗粒度方式是啟動(dòng)時(shí)直接向Master申請(qǐng)執(zhí)行全部Task的資源,并等所有計(jì)算任務(wù)結(jié)束后才釋放資源;細(xì)粒度方式是根據(jù)Task需要的資源不停的申請(qǐng)和歸還。兩個(gè)方式各有利弊,粗粒度的優(yōu)點(diǎn)是調(diào)度成本小,但是會(huì)因木桶效應(yīng)造成資源長(zhǎng)期被霸占;細(xì)粒度沒(méi)有木桶效應(yīng),但是調(diào)度上的管理成本較高。
YARN模式:
在洗牌過(guò)程中StageA每個(gè)當(dāng)前的Task會(huì)把自己的Partition按照stageB中Partition的要求做Hash產(chǎn)生stageB中task數(shù)量的Partition(這里特別強(qiáng)調(diào)是每個(gè)stageA的task),這樣就會(huì)有l(wèi)en(stageA.task)*len(stageB.task)這么多的小file在中間過(guò)程產(chǎn)生,如果要緩存RDD結(jié)果還需要維護(hù)到內(nèi)存,下個(gè)stageB需要merge這些file又涉及到網(wǎng)絡(luò)的開(kāi)銷(xiāo)和離散文件的讀取,所以說(shuō)超過(guò)一定規(guī)模的任務(wù)用Hash Base模式是非常吃硬件的。
盡管后來(lái)Spark版本推出了Consolidate對(duì)基于Hash的模式做了優(yōu)化,但是只能在一定程度上減少block file的數(shù)量,沒(méi)有根本解決上面的缺陷。
Sort Base Shuffle(spark1.2開(kāi)始默認(rèn)):
Sort模式下StageA每個(gè)Task會(huì)產(chǎn)生2個(gè)文件:內(nèi)容文件和索引文件。內(nèi)容文件是根據(jù)StageB中Partition的要求自己先sort好并生成一個(gè)大文件;索引文件是對(duì)內(nèi)容文件的輔助說(shuō)明,里面維護(hù)了不同的子partition之間的分界,配合StageB的Task來(lái)提取信息。這樣中間過(guò)程產(chǎn)生文件的數(shù)量由len(stageA.task)*len(stageB.task)減少到2* len(stageA.task),StageB對(duì)內(nèi)容文件的讀取也是順序的。Sort帶來(lái)的另一個(gè)好處是,一個(gè)大文件對(duì)比與分散的小文件更方便壓縮和解壓,通過(guò)壓縮可以減少網(wǎng)絡(luò)IO的消耗。(PS:但是壓縮和解壓的過(guò)程吃CPU,所以要合理評(píng)估)
Sort和Hash模式通過(guò)spark.shuffle.manager來(lái)配置的。
Storage模塊:
存儲(chǔ)介質(zhì):內(nèi)存、磁盤(pán)、Tachyon(這貨是個(gè)分布式內(nèi)存文件,與Redis不一樣,Redis是分布式內(nèi)存數(shù)據(jù)庫(kù)),存儲(chǔ)級(jí)別就是它們單獨(dú)或者相互組合,再配合一些容錯(cuò)、序列化等策略。例如內(nèi)存+磁盤(pán)。
負(fù)責(zé)存儲(chǔ)的組件是BlockManager,在Master(Dirver)端和Slaver(Executor)端都有BlockManager,分工不同。Slaver端的將自己的BlockManager注冊(cè)給Master,負(fù)責(zé)真正block;Master端的只負(fù)責(zé)管理和調(diào)度。
Storage模塊運(yùn)行時(shí)內(nèi)存默認(rèn)占Executor分配內(nèi)存的60%,所以合理的分配Executor內(nèi)存和選擇合適的存儲(chǔ)級(jí)別需要平衡下Spark的性能和穩(wěn)定。
Spark的出現(xiàn)很好的彌補(bǔ)了Hadoop在大數(shù)據(jù)處理上的不足,同時(shí)隨著枝葉不斷散開(kāi),出線(xiàn)了很多的衍生的接口模塊豐富了Spark的應(yīng)用場(chǎng)景,也降低了Spark與其他技術(shù)的接入門(mén)檻。
以上就是Spark原理的實(shí)例分析,小編相信有部分知識(shí)點(diǎn)可能是我們?nèi)粘9ぷ鲿?huì)見(jiàn)到或用到的。希望你能通過(guò)這篇文章學(xué)到更多知識(shí)。更多詳情敬請(qǐng)關(guān)注億速云行業(yè)資訊頻道。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。