Spark源碼分析(3) RDD 的轉(zhuǎn)換

RDD 的轉(zhuǎn)換可以產(chǎn)生新的 RDD。
RDD轉(zhuǎn)換圖

如上圖,外圈是 RDD 的轉(zhuǎn)換成洗,內(nèi)圈紅色 RDD 是轉(zhuǎn)換產(chǎn)生的新 RDD五督。
按顏色區(qū)分轉(zhuǎn)換:

  • 綠色是單 RDD 窄依賴轉(zhuǎn)換
  • 黑色是多 RDD 窄依賴轉(zhuǎn)換
  • 紫色是 KV 洗牌型轉(zhuǎn)換
  • 黃色是重分區(qū)轉(zhuǎn)換
  • 藍(lán)色是特例的轉(zhuǎn)換

單 RDD 窄依賴轉(zhuǎn)換

MapPartitionRDD

這個(gè) RDD 在第一次分析中已經(jīng)分析過。簡(jiǎn)單復(fù)述一下:

  • 依賴列表:一個(gè)窄依賴瓶殃,依賴上游 RDD
  • 分區(qū)列表:上游 RDD 的分區(qū)列表
  • 計(jì)算流程:映射關(guān)系(輸入一個(gè)分區(qū)充包,返回一個(gè)迭代器)
  • 分區(qū)器 :上游 RDD 的分區(qū)器
  • 存儲(chǔ)位置:上游 RDD 的優(yōu)先位置
    可見除了計(jì)算流程,其他都是上游 RDD 的內(nèi)容遥椿。
  1. map 傳入一個(gè)帶“值到值”轉(zhuǎn)化函數(shù)的迭代器(例如字符串到字符串長(zhǎng)度)
  2. mapPartitions 傳入一個(gè)“迭代器到迭代器”的轉(zhuǎn)化函數(shù)基矮,如果需要按分區(qū)做一些比較重的過程(例如數(shù)據(jù)庫連接等)
  3. flatMap 傳入一個(gè)“迭代器到迭代器的迭代器”的轉(zhuǎn)化函數(shù)(例如押逼,統(tǒng)計(jì)字母策肝,“字符串的迭代器”到“‘字符的迭代器’的迭代器”)
  4. filter 傳入了一個(gè)帶“值到布爾值”篩選函數(shù)的迭代器

PartitionwiseSampledRDD

在分區(qū)中采樣的RDD

  • 分區(qū)列表:在上游的分區(qū)的基礎(chǔ)上包裝一個(gè)采樣過程内颗,形成一個(gè)新的分區(qū)PartitionwiseSampledRDDPartition
  • 計(jì)算流程:采樣器返回的迭代器
  • 其他成分:與上游 RDD 相同
    PartitionwiseSampledRDD升薯,有放回的采樣用泊松采樣器立润,無放回的采樣用伯努利采樣器屉来,傳給分區(qū)器焕阿。

多 RDD 窄依賴

UnionRDD

  • 依賴列表:每個(gè)上游 RDD 一個(gè)RangeDependency钾挟,每個(gè)RangeDependency依賴上游 RDD 的所有分區(qū)
  • 分區(qū)列表:每個(gè)上游 RDD 一個(gè)UnionPartition舔株,構(gòu)成列表
  • 計(jì)算流程:獲得目標(biāo)分區(qū)的迭代器
  • 分區(qū)器 :None
  • 存儲(chǔ)位置:每個(gè)上游 RDD 的優(yōu)先位置

CartesianRDD

笛卡爾積莺琳,是兩個(gè) RDD 每個(gè)數(shù)據(jù)都進(jìn)行一次關(guān)聯(lián)。下文中兩個(gè) RDD 的關(guān)聯(lián)中载慈,兩個(gè) RDD 分別稱為 rdd1惭等、rdd2。

  • 依賴列表:兩個(gè)窄依賴組成的數(shù)組娃肿,分別依賴 rdd1咕缎、rdd2
  • 分區(qū)列表:“rdd1的分區(qū)數(shù) 乘以 rdd2的分區(qū)數(shù)”個(gè)分區(qū)
  • 計(jì)算流程:rdd1的一條記錄與 rdd2的一條記錄合成元組
  • 分區(qū)器 :None
  • 存儲(chǔ)位置:rdd1、rdd2的存儲(chǔ)位置的積

洗牌型轉(zhuǎn)換

洗牌型轉(zhuǎn)換料扰,是多個(gè) RDD 關(guān)聯(lián)的的轉(zhuǎn)換凭豪。

CoGroupedRDD

多個(gè)源 RDD 依據(jù) key 關(guān)聯(lián),key 相同的合并晒杈,形成最終的目標(biāo) RDD嫂伞。

  • 依賴列表:每個(gè)源 RDD 一個(gè)依賴,構(gòu)成列表拯钻。如果源 RDD 的分區(qū)器與目標(biāo)的分區(qū)器相同帖努,則是1-to-1依賴,如果不同粪般,則是洗牌依賴
  • 分區(qū)列表:目標(biāo) RDD 分區(qū)器指定的分區(qū)數(shù)量個(gè)CoGroupPartition拼余,每個(gè)分區(qū)記錄了數(shù)據(jù)來源分區(qū)。其中如果是洗牌依賴的數(shù)據(jù)源亩歹,需要洗牌過程匙监,具體洗牌過程以后再分析
  • 計(jì)算流程:返回一個(gè)迭代器凡橱,迭代對(duì)象是 key 和 key 對(duì)應(yīng)源分區(qū)迭代器的數(shù)組 組成的元祖
  • 分區(qū)器 :目標(biāo) RDD 的分區(qū)器
  • 存儲(chǔ)位置:None

ShuffledRDD

同樣是多個(gè)源 RDD 依據(jù) key 關(guān)聯(lián),key 相同的做排序或聚合運(yùn)算亭姥,形成最終的目標(biāo) RDD稼钩。

  • 依賴列表:一個(gè)洗牌依賴,依賴所有上游 RDD
  • 分區(qū)列表:目標(biāo) RDD 分區(qū)器指定的分區(qū)數(shù)量個(gè)ShuffledRDDPartition达罗,每個(gè)分區(qū)只有一個(gè)編號(hào)(因?yàn)槊總€(gè)上游分區(qū))
  • 計(jì)算流程:洗牌過程坝撑,具體洗牌過程以后再分析
  • 分區(qū)器 :目標(biāo) RDD 的分區(qū)器
  • 存儲(chǔ)位置:None

除了這五個(gè)成員以外,還有另外幾個(gè)重要的成員:序列化器粮揉、key 排序器巡李、聚合器、map 端合并器滔蝉,他們都將用于洗牌

其他

  • coalesce击儡,是減少分區(qū)數(shù)量塔沃,可以在過濾之后蝠引,使數(shù)據(jù)更集中,以提高效率
  • repartition蛀柴,是重新分區(qū)螃概,增加或減少分區(qū)數(shù)量,數(shù)據(jù)隨機(jī)重新分配鸽疾,可以消除分區(qū)間的數(shù)據(jù)量差異
  • pipe吊洼,是與外部程序管道關(guān)聯(lián),從外部程序中獲取數(shù)據(jù)制肮。

Scala語法

在 RDD.scala中冒窍,幾乎每一個(gè)轉(zhuǎn)換和操作函數(shù)都會(huì)有一個(gè)withScope,例如:

def map[U: ClassTag](f: T => U): RDD[U] = withScope {
    val cleanF = sc.clean(f)
    new MapPartitionsRDD[U, T](this, (context, pid, iter) => iter.map(cleanF))
}
def flatMap[U: ClassTag](f: T => TraversableOnce[U]): RDD[U] = withScope {
    val cleanF = sc.clean(f)
    new MapPartitionsRDD[U, T](this, (context, pid, iter) => iter.flatMap(cleanF))
}

withScope是一個(gè)函數(shù)豺鼻,調(diào)用了RDDOperationScope.withScope方法:

private[spark] def withScope[U](body: => U): U = RDDOperationScope.withScope[U](sc)(body)

withScope就像是一個(gè) AOP(面向切面編程)综液,嵌入到所有RDD 的轉(zhuǎn)換和操作的函數(shù)中,RDDOperationScope會(huì)把調(diào)用棧記錄下來儒飒,用于繪制Spark UI的 DAG(有向無環(huán)圖谬莹,可以理解為 Spark 的執(zhí)行計(jì)劃)。

我們用下面的代碼簡(jiǎn)單演示一下 Scala 用函數(shù)做 AOP:

object Day1 {
  def main(args: Array[String]) = {
    Range(1,5).foreach(twice)
    println()
    Array("China", "Beijing", "HelloWorld").foreach(length)
  }

  def twice(i: Int): Int = aopPrint {
    i * 2
  }

  def length(s: String): Int = aopPrint {
    s.length
  }

  def aopPrint[U](i: => U): U = {
    print(i + " ")
    i
  }
}

aopPrint的 入?yún)⑹恰耙粋€(gè)返回類型為U的函數(shù)”桩了。這段程序中aopPrint就是一個(gè)模擬的切面附帽,作用是把所有的函數(shù)返回值打印出來。結(jié)果是:

2 4 6 8 
5 7 10

從代碼上看井誉,aopPrint并沒有降低代碼的可讀性蕉扮。讀者依然能很清楚地讀懂twicelength函數(shù)。打印返回結(jié)果這個(gè)流程是獨(dú)立于函數(shù)之外的切面颗圣。


結(jié)論

  1. RDD 的轉(zhuǎn)換分圖上幾種
  2. RDD 的轉(zhuǎn)換可以看成是產(chǎn)生新的 RDD喳钟,而新的 RDD 記錄了每一個(gè)分區(qū)依賴上游的哪些分區(qū)爪模、每個(gè)分區(qū)如何用上游分區(qū)計(jì)算而來

本文源碼

spark/core/rdd包下的部分 RDD 類spark/core/src/main/scala/org/apache/spark/rdd at master · apache/spark · GitHub


@ Kangying Village, Beijing, China


最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市荚藻,隨后出現(xiàn)的幾起案子屋灌,更是在濱河造成了極大的恐慌,老刑警劉巖应狱,帶你破解...
    沈念sama閱讀 211,290評(píng)論 6 491
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件共郭,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡疾呻,警方通過查閱死者的電腦和手機(jī)除嘹,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,107評(píng)論 2 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來岸蜗,“玉大人尉咕,你說我怎么就攤上這事×г溃” “怎么了年缎?”我有些...
    開封第一講書人閱讀 156,872評(píng)論 0 347
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)铃慷。 經(jīng)常有香客問我单芜,道長(zhǎng),這世上最難降的妖魔是什么犁柜? 我笑而不...
    開封第一講書人閱讀 56,415評(píng)論 1 283
  • 正文 為了忘掉前任洲鸠,我火速辦了婚禮,結(jié)果婚禮上馋缅,老公的妹妹穿的比我還像新娘扒腕。我一直安慰自己,他們只是感情好萤悴,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,453評(píng)論 6 385
  • 文/花漫 我一把揭開白布瘾腰。 她就那樣靜靜地躺著,像睡著了一般稚疹。 火紅的嫁衣襯著肌膚如雪居灯。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,784評(píng)論 1 290
  • 那天内狗,我揣著相機(jī)與錄音怪嫌,去河邊找鬼。 笑死柳沙,一個(gè)胖子當(dāng)著我的面吹牛岩灭,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播赂鲤,決...
    沈念sama閱讀 38,927評(píng)論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼噪径,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼柱恤!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起找爱,我...
    開封第一講書人閱讀 37,691評(píng)論 0 266
  • 序言:老撾萬榮一對(duì)情侶失蹤梗顺,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后车摄,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體寺谤,經(jīng)...
    沈念sama閱讀 44,137評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,472評(píng)論 2 326
  • 正文 我和宋清朗相戀三年吮播,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了变屁。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,622評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡意狠,死狀恐怖粟关,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情环戈,我是刑警寧澤闷板,帶...
    沈念sama閱讀 34,289評(píng)論 4 329
  • 正文 年R本政府宣布,位于F島的核電站谷市,受9級(jí)特大地震影響蛔垢,放射性物質(zhì)發(fā)生泄漏击孩。R本人自食惡果不足惜迫悠,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,887評(píng)論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望巩梢。 院中可真熱鬧创泄,春花似錦、人聲如沸括蝠。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,741評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽忌警。三九已至搁拙,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間法绵,已是汗流浹背箕速。 一陣腳步聲響...
    開封第一講書人閱讀 31,977評(píng)論 1 265
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留朋譬,地道東北人盐茎。 一個(gè)月前我還...
    沈念sama閱讀 46,316評(píng)論 2 360
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像徙赢,于是被迫代替她去往敵國和親字柠。 傳聞我的和親對(duì)象是個(gè)殘疾皇子探越,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,490評(píng)論 2 348

推薦閱讀更多精彩內(nèi)容