Spark RDD的依賴於DAG的工作原理

在進行本篇之前,如果還有對Spark的一些基礎概念不太明白的可以參考一下這篇博文:
Spark核心組件、運行架構

RDD的依賴

RDD是一種彈性分佈式數據集,我們以圖示的形式來展示一下它的原理:

在這裏插入圖片描述

RDD的寬窄依賴

Lineage:血統、遺傳

  • RDD最重要的特性之一,保存了RDD的依賴關係;
  • RDD實現了基於Lineage的容錯機制;
    依賴關係
    寬依賴:一個父RDD的分區被子RDD的多個分區使用;
    在這裏插入圖片描述
    在這裏插入圖片描述
    窄依賴:一個父RDD的分區被子RDD的一個分區使用;
    在這裏插入圖片描述
    例如union:
    在這裏插入圖片描述
    在這裏插入圖片描述
    常見的寬依賴有:groupByKey,partitionBy,reduceByKey,Join(父RDD不是hash-partitioned :除此之外的,rdd 的join api是寬依賴)。
    常見的窄依賴有:map,filter,union,mapPartitions,mapValues,join(父RDD是hash-partitioned :如果JoinAPI之前被調用的RDD API是寬依賴(存在shuffle), 而且兩個join的RDD的分區數量一致,join結果的rdd分區數量也一樣,這個時候join api是窄依賴)。
    寬依賴對比窄依賴
  • 寬依賴對應shuffle操作,需要在運行時將同一個父RDD的分區傳入到不同的子RDD分區中,不同的分區可能位於不同的節點,就可能涉及多個節點間數據傳輸
  • 當RDD分區丟失時,Spark會對數據進行重新計算,對於窄依賴只需重新計算一次子RDD的父RDD分區。相比於寬依賴,窄依賴對優化更有利。

DAG工作原理

根據RDD之間的依賴關係,形成一個DAG(有向無環圖)。
DAGScheduler將DAG劃分爲多個Stage

  • 劃分依據:是否發生寬依賴(Shuffle)
  • 劃分規則:從後往前,遇到寬依賴切割爲新的Stage
  • 每個Stage由一組並行的Task組成
    DAGScheduler
    有向無環圖調度器。
  • 基於DAG劃分Stage 並以TaskSet的形勢提交Stage給TaskScheduler;
  • 負責將作業拆分成不同階段的具有依賴關係的多批任務;
  • 最重要的任務之一就是:計算作業和任務的依賴關係,制定調度邏輯。
  • 在SparkContext初始化的過程中被實例化,一個SparkContext對應創建一個DAGScheduler。
    在這裏插入圖片描述
    TaskSceduler:
    任務調度器。將TaskSet提交給Worker(集羣)運行並返回結果;負責每個具體任務的實際物理調度。
    在這裏插入圖片描述
    下面來張總表供大家仔細查看:
    在這裏插入圖片描述
    在這裏插入圖片描述

劃分Stage的原因

數據本地化

  • 移動計算,而不是移動數據;
    -保證一個Stage內不會發生數據移動;

建議

  • 儘量避免Shuffle
  • 提前部分聚合減少數據移動

Spark Shuffler過程

在分區之間重新分配數據

  • 父RDD中同一分區中的數據按照算子要求重新進入子RDD的不同分區中
  • 中間結果寫入磁盤
  • 由子RDD拉取數據,而不是由父RDD推送
  • 默認情況下,Shuffle不會改變分區數量
    在這裏插入圖片描述