為什么要設計RDD
????? 網(wǎng)上資料很多鸣剪,這里我給羅列出來,許多的迭代算法和交互式數(shù)據(jù)挖掘工具,這些應用場景的共同點是:在不同的運行階段或者說是計算階段慷嗜,都會重用中間結果,即一個階段的輸出會作為下一個輸出丹壕,而Hadoop的mapreduce 會把處理的中間結果放入到HDFS上庆械,這樣極大的增加了磁盤讀寫的負擔。
??? RDD 就是滿足這個減少對I/O的負擔而提出的菌赖,提供一個抽象的數(shù)據(jù)結構缭乘,不必擔心底層數(shù)據(jù)的分布性,只需要將具體的應用邏輯表達為一些列的轉換處理琉用,不同的RDD之間的轉換操作形成依賴關系堕绩,可實現(xiàn)管道化策幼,從而避免中間結果,減少磁盤I/O的操作奴紧。就是實現(xiàn)RDD 這個數(shù)據(jù)結構時候特姐,可以重用中間結果,每個階段的中間結果有依賴關系黍氮,可以相互轉化到逊。減少I/O操作,降低讀寫開銷滤钱,提高運算效率觉壶。
什么是RDD?
一個RDD是一個分布式對象集合。本質(zhì)上是一個只讀的分區(qū)集合件缸。每個RDD 可以分成多個分區(qū)铜靶,每個分區(qū)上有多個數(shù)據(jù)集片段。
并且他炊。一個RDD上的不同的分區(qū)可以被保存在集群中不同的worknode 上争剿。從而使集群在不同的節(jié)點上實行并行運算。
關鍵字:高度受限痊末,只讀記錄分區(qū)集合蚕苇,不能修改
RDD還提供了一種高度受限的共享內(nèi)存模型。 【是一個只讀的記錄分區(qū)集合凿叠,不能直接修改】涩笤。只能基于穩(wěn)定的物理存儲中的數(shù)據(jù)集來創(chuàng)建RDD『屑或者通過在其他的RDD上執(zhí)行確定的轉換操蹬碧。(map, join,groupby)而創(chuàng)建而得到新的RDD。
RDD提供一組豐富的操作以及支持常見的數(shù)據(jù)運算炒刁,分為 Action 【行動】和轉換【Transformation】兩個類型恩沽,前者用于執(zhí)行計算并指定輸出形式,——> Action 后者用于只能夠RDD之間的相互關系——> Transformation
? Action and Transformation 的區(qū)別
1.前者用于執(zhí)行計算并指定輸出形式翔始,——> Action 后者用于只能夠RDD之間的相互關系——> Transformation
2.轉換操作【 map ,join,filter groupBy 】 接受RDD并返回RDD罗心。
3.行動操作【count,collect】接受RDD城瞎,但是返回非RDD(即一個輸出一個值或者結果)
RDD提供的轉換接口都非常簡單渤闷, 都是類似map,filter,groupBy ,join 等數(shù)據(jù)轉換操作。 因此全谤,RDD 比較適合對于數(shù)據(jù)集元素中執(zhí)行相同操作的批處理式應用肤晓。
RDD 執(zhí)行過程
1. RDD 讀取外部數(shù)據(jù)源,或者再內(nèi)存中進行創(chuàng)建
2.RDD經(jīng)過一系列的轉換操作,每一次都會產(chǎn)生不同的RDD补憾,共下一個轉換使用
3.整個流程中的最后一個RDD經(jīng)過Action 操作驚醒處理漫萄,并輸出外部數(shù)據(jù)源。
注釋: RDD采用惰性調(diào)用盈匾,即在RDD的執(zhí)行過程中腾务,真正的計算發(fā)生在RDD的Action 操作,對于Action 操作之前的所有Transformation 操作削饵,Spark只記錄Transformation應用的一些基礎數(shù)據(jù)集以及RDD生成軌跡岩瘦,即各個RDD之間的相互依賴關系,而不會觸發(fā)真正的運算 只有在Action 時候 才會計算并返回一個值窿撬。
Spark 轉換和行動操作
1.在輸入邏輯是上生成2個RDD 命名為A启昧,D,? 經(jīng)一系列的Transformation [轉換]操作劈伴,會在最后生成一個RDD 這里取名為F密末,當要輸出時候,也就是F進行Action 作時候是跛璧,Spark會根據(jù)RDD的依賴關系生成DAG 從起點進行真正的計算严里,之前都是邏輯上的,只是記錄了各個RDD之間的依賴關系追城。
spark的數(shù)據(jù)處理框架 從一定程度上是對mapreduce 的擴展刹碾。執(zhí)行mapreduce并不擅長的迭代式,交互式座柱,流式計算迷帜。 因為spar創(chuàng)造性提出了RDD概念
Spark 編程:Scala 版
val sc=SparkContext()
對于Spark程序而言,要想進行操作辆布,必須創(chuàng)建一個上下文瞬矩。在創(chuàng)建上下文的過程中,集群申請資源以及構建相應的運行環(huán)境锋玲,一般來說要多SparkConnect 傳入四個變量:
1.spark://localhost:7077 [集群在本地啟動監(jiān)聽7077 端口]
2.spark程序的標識
3.spark的安裝路徑
4.傳入這個Spark程序的jar 包
val? file=sc.textFile("hdfs:///root/datadir")
利用textFile 接口從指定的目錄下讀取文件 并返回一個變量file
val fileRDD=file.filter(_.contanins("hello, word"))
對文件進行過濾操作,傳入的是function的對象涵叮。
spark編程中重要的幾個概念
1.彈性分布式數(shù)據(jù)集RDD
2.創(chuàng)建操作惭蹂,即申請資源內(nèi)存一系列的SparkConnect,將內(nèi)存中的集合或者是外部文件系統(tǒng)作為輸入源
3.轉換操作。將一個RDD通過一定的操作轉換成另一個RDD
4.控制操作: 對RDD持久化割粮,可以讓RDD保存在磁盤或者內(nèi)存中盾碗,以便后續(xù)重復使用
5.行動操作: 我的理解就是RDD調(diào)用相關方法
RDD特性? ——實現(xiàn)高效計算的主要原因
1.高效的容錯性。現(xiàn)有的分布式共享內(nèi)存舀瓢,鍵值存儲廷雅,內(nèi)存數(shù)據(jù)庫,為了實現(xiàn)容錯,必須在集群節(jié)點之間進行數(shù)據(jù)復制或者記錄日志? 也即是在節(jié)點之間會發(fā)生大量的數(shù)據(jù)傳輸航缀。這對于數(shù)據(jù)密集型應用而言會帶來很大的開銷商架,
2.在RDD的設計中,數(shù)據(jù)只讀芥玉,不可修改蛇摸,如果修改數(shù)據(jù),必須從父類的RDD轉換到子類的RDD灿巧,由此在不同的RDD上建立血緣聯(lián)系
3.中間結果持久化到內(nèi)存中赶袄,數(shù)據(jù)在內(nèi)存中的多個RDD操作之間進行傳遞,不需要寫到磁盤抠藕,減少I/O開銷饿肺。
4.存放的數(shù)據(jù)可以使Java對象,避免了不必要的對象的序列化和反序列化的開銷
RDD之間的依賴關系
不同的RDD中在不同的操作會在不同的RDD中產(chǎn)生不同的依賴盾似,RDD中的依賴分為窄依賴和寬依賴
窄依賴和寬依賴
窄依賴表現(xiàn)為一個父RDD的分區(qū)對應于一個子RDD的分區(qū)唬格,或者多個父RDD的分區(qū)對應一個子RDD的分區(qū)。
寬依賴表現(xiàn)為一個父類的RDD的一個分區(qū)對應一個子RDD的多個分區(qū)
辨別:如果存在一個父類的RDD的一個分區(qū)對應一個子RDD的多個分區(qū)颜说,則是寬依賴购岗,否則是窄依賴。
兩者依賴包含的幾種操作
窄依賴【map, filter,union】
寬依賴【groupBy,sortByKey】
【join】連接操作分為2種情況
1.對輸入進行協(xié)同劃分门粪,屬于窄依賴喊积,所謂協(xié)同劃分是指多個父RDD的某一個分區(qū)的所有的鍵key落在子RDD的同一個分區(qū)內(nèi),不會產(chǎn)生同一個父RDD的某一個分區(qū)玄妈,落在子RDD的兩個分區(qū)的情況乾吻。
2.對輸入做非協(xié)同劃分,屬于寬依賴拟蜻。?
兩者依賴應用的場景選擇
對于窄依賴的RDD绎签,可以以流水線的方式計算所有父分區(qū),不會造成網(wǎng)絡之間的數(shù)據(jù)混合酝锅。
對于寬依賴的RDD诡必,則通常伴隨著Shuffle操作,即首先需要計算好所有父分區(qū)數(shù)據(jù)搔扁,然后在節(jié)點之間進行Shuffle爸舒。
窄依賴寬依賴的區(qū)別
????? 在兩種依賴關系中,窄依賴的失敗恢復更為高效稿蹲,它只需要根據(jù)父RDD分區(qū)重新計算丟失的分區(qū)即可(不需要重新計算所有分區(qū))扭勉,而且可以并行地在不同節(jié)點進行重新計算。而對于寬依賴而言苛聘,單個節(jié)點失效通常意味著重新計算過程會涉及多個父RDD分區(qū)涂炎,開銷較大忠聚。此外,Spark還提供了數(shù)據(jù)檢查點和記錄日志唱捣,用于持久化中間RDD两蟀,從而使得在進行失敗恢復時不需要追溯到最開始的階段爷光。在進行故障恢復時,Spark會對數(shù)據(jù)檢查點開銷和重新計算RDD分區(qū)的開銷進行比較蛀序,從而自動選擇最優(yōu)的恢復策略欢瞪。
階段的劃分
Spark通過分析各個RDD的依賴關系生成了DAG遣鼓,再通過分析各個RDD中的分區(qū)之間的依賴關系來決定如何劃分階段,具體劃分方法是:
在DAG中進行反向解析重贺,遇到寬依賴就斷開,遇到窄依賴就把當前的RDD加入到當前的階段中气笙;將窄依賴盡量劃分在同一個階段中,可以實現(xiàn)流水線計算潜圃,假設從HDFS中讀入數(shù)據(jù)生成3個不同的RDD(即A、C和E)谭期,通過一系列轉換操作后再將計算結果保存回HDFS。對DAG進行解析時隧出,在依賴圖中進行反向解析,由于從RDD A到RDD B的轉換以及從RDD B和F到RDD G的轉換胀瞪,都屬于寬依賴针余,因此,在寬依賴處斷開后可以得到三個階段赏廓,即階段1涵紊、階段2和階段3♂C可以看出,在階段2中颤练,從map到union都是窄依賴既忆,這兩步操作可以形成一個流水線操作,比如,分區(qū)7通過map操作生成的分區(qū)9患雇,可以不用等待分區(qū)8到分區(qū)9這個轉換操作的計算結束跃脊,而是繼續(xù)進行union操作,轉換得到分區(qū)13苛吱,這樣流水線執(zhí)行大大提高了計算的效率酪术。
RDD運行過程
(1)創(chuàng)建RDD對象;
(2)SparkContext負責計算RDD之間的依賴關系翠储,構建DAG绘雁;
(3)DAGScheduler負責把DAG圖分解成多個階段,每個階段中包含了多個任務援所,每個任務會被任務調(diào)度器分發(fā)給各個工作節(jié)點(Worker Node)上的Executor去執(zhí)行庐舟。