- Spark核心技術(shù)與高級應(yīng)用
- 于俊等
- 92字
- 2019-01-01 01:24:38
第4章
編程模型
不自見,故明;不自是,故彰;不自伐,故有功;不自矜,故能長。
——《道德經(jīng)》第二十二章
在面對自我的問題上,不自我表揚,反能顯明;不自以為是,反能彰顯;不自我夸耀,反能見功;不自我矜恃,反能長久。
與許多專有的大數(shù)據(jù)處理平臺不同,基于Spark的大數(shù)據(jù)處理平臺,建立在統(tǒng)一抽象的RDD之上,這是Spark這朵小火花讓人著迷的地方,也是學(xué)習(xí)Spark編程模型的瓶頸所在,充滿了很深的理論和工程背景。
本章重點講解Spark編程模型的最主要抽象,第一個抽象是RDD(Resilient Distributed Dataset,彈性分布式數(shù)據(jù)集),它是一種特殊集合,支持多種來源,有容錯機制,可以被緩存,支持并行操作;Spark的第二個抽象是兩種共享變量,即支持并行計算的廣播變量和累加器。
要理解Spark,就必須理解RDD。在學(xué)習(xí)過程中,希望能時刻警醒自己,做到不自見、不自是、不自伐、不自矜。
4.1 RDD介紹
基于Spark的大數(shù)據(jù)處理平臺,建立在統(tǒng)一抽象的RDD之上,RDD是Spark圍繞的核心概念,也是最主要的抽象之一。對于RDD和Spark,RDD是一種具有容錯性基于內(nèi)存的集群計算抽象方法,Spark則是這個抽象方法的實現(xiàn)。
4.1.1 RDD特征
簡單來說,Spark一切都是基于RDD的,RDD就是Spark輸入的數(shù)據(jù),作為輸入數(shù)據(jù)的每個RDD有五個特征,其中分區(qū)、一系列的依賴關(guān)系和函數(shù)是三個基本特征,優(yōu)先位置和分區(qū)策略是可選特征。
1)分區(qū)(partition):有一個數(shù)據(jù)分片列表,能夠?qū)?shù)據(jù)進行切分,切分后的數(shù)據(jù)能夠進行并行計算,是數(shù)據(jù)集的原子組成部分。
2)函數(shù)(compute):計算每個分片,得出一個可遍歷的結(jié)果,用于說明在父RDD上執(zhí)行何種計算。
3)依賴(dependency):計算每個RDD對父RDD的依賴列表,源RDD沒有依賴,通過依賴關(guān)系描述血統(tǒng)(lineage)。
4)優(yōu)先位置(可選):每一個分片的優(yōu)先計算位置(preferred locations),比如HDFS的Block的所在位置應(yīng)該是優(yōu)先計算的位置。
5)分區(qū)策略(可選):描述分區(qū)模式和數(shù)據(jù)存放的位置,鍵-值對(key-value)的RDD根據(jù)哈希值進行分區(qū),類似于MapReduce中的Paritioner接口,根據(jù)key來決定分配位置。
常用的RDD有很多種,可以說,每個Transformation操作都會產(chǎn)生一種RDD,這里我們以HadoopRDD、MappedRDD、FilteredRDD、JoinedRDD為例對特征進行說明,如表4-1所示。
表4-1 常用RDD特征說明

4.1.2 RDD依賴
Spark中RDD的數(shù)據(jù)結(jié)構(gòu)里很重要的一個域是對父RDD的依賴,Spark中的依賴關(guān)系主要體現(xiàn)為兩種形式,窄依賴(narrow dependency)和寬依賴(wide dependency)。
圖4-1對窄依賴和寬依賴進行了說明。

圖4-1 窄依賴和寬依賴
1. 窄依賴
窄依賴是指父RDD的每一個分區(qū)最多被一個子RDD的分區(qū)所用,表現(xiàn)為一個父RDD的分區(qū)對應(yīng)于一個子RDD的分區(qū)(第一類),或多個父RDD的分區(qū)對應(yīng)于一個子RDD的分區(qū)(第二類),也就是說一個父RDD的一個分區(qū)不可能對應(yīng)一個子RDD的多個分區(qū)。
圖4-1中,Map/Filter和Union屬于第一類,對輸入進行協(xié)同劃分(co-partitioned)的Join屬于第二類(協(xié)同劃分,可以理解為指多個父RDD的某一分區(qū)的所有key,落在子RDD的同一分區(qū)的象限,不會產(chǎn)生同一父RDD的某一分區(qū),落在子RDD的兩個分區(qū)的情況)。
進一步說,子RDD的每個分區(qū)依賴于常數(shù)個父分區(qū),與數(shù)據(jù)規(guī)模無關(guān),輸入輸出是一對一的算子。當子RDD的每個分區(qū)依賴單個父分區(qū)時,分區(qū)結(jié)構(gòu)不會發(fā)生變化,如Map、f latMap;當子RDD依賴多個父分區(qū)時,分區(qū)結(jié)構(gòu)發(fā)生變化,如Union。
2.寬依賴
寬依賴是指子RDD的每個分區(qū)都依賴于所有父RDD的所有分區(qū)或多個分區(qū),也就是說存在一個父RDD的一個分區(qū)對應(yīng)一個子RDD的多個分區(qū)。
圖4-1中的groupByKey和未經(jīng)過協(xié)同劃分的Join屬于寬依賴。
3.依賴關(guān)系說明
對兩種依賴關(guān)系進行如下說明:
窄依賴的RDD可以通過相同的鍵進行聯(lián)合分區(qū),整個操作都可以在一個集群節(jié)點上進行,以流水線(pipeline)的方式計算所有父分區(qū),不會造成網(wǎng)絡(luò)之間的數(shù)據(jù)混合。
寬依賴RDD會涉及數(shù)據(jù)混合,寬依賴需要首先計算好所有父分區(qū)數(shù)據(jù),然后在節(jié)點之間進行Shuffle。
窄依賴能夠更有效地進行失效節(jié)點的恢復(fù),重新計算丟失RDD分區(qū)的父分區(qū),不同節(jié)點之間可以并行計算;而對于一個寬依賴關(guān)系的血統(tǒng)(lineage)圖,單個節(jié)點失效可能導(dǎo)致
這個RDD的所有祖先丟失部分分區(qū),因而需要整體重新計算。
注意
Shuffle執(zhí)行時固化操作,以及采取Persist緩存策略,可以在固化點,或者緩存點重新計算。
執(zhí)行時,調(diào)度程序會檢查依賴性的類型,將窄依賴的RDD劃到一組處理當中,即Stage。寬依賴在一個執(zhí)行中會跨越連續(xù)的Stage,同時需要顯式指定多個子RDD的分區(qū)。
- 同步:秩序如何從混沌中涌現(xiàn)
- Python絕技:運用Python成為頂級數(shù)據(jù)工程師
- 數(shù)據(jù)庫原理及應(yīng)用教程(第4版)(微課版)
- Python數(shù)據(jù)挖掘:入門、進階與實用案例分析
- 卷積神經(jīng)網(wǎng)絡(luò)的Python實現(xiàn)
- Python數(shù)據(jù)分析:基于Plotly的動態(tài)可視化繪圖
- Python醫(yī)學(xué)數(shù)據(jù)分析入門
- 大數(shù)據(jù)架構(gòu)和算法實現(xiàn)之路:電商系統(tǒng)的技術(shù)實戰(zhàn)
- Python金融數(shù)據(jù)分析(原書第2版)
- 深入淺出Greenplum分布式數(shù)據(jù)庫:原理、架構(gòu)和代碼分析
- 圖數(shù)據(jù)實戰(zhàn):用圖思維和圖技術(shù)解決復(fù)雜問題
- 科研統(tǒng)計思維與方法:SPSS實戰(zhàn)
- 機器學(xué)習(xí):實用案例解析
- 信息融合中估計算法的性能評估
- PostgreSQL高可用實戰(zhàn)