RDD原理詳解

RDD 原理

  • 在這些特性中,最難實現的是容錯性,一般來說,分佈式數據集的容錯性有兩種方式,一般來說,分佈式數據集的容錯性有兩種方式:即數據檢查點和記錄數據的更新。我們面向的是大規模數據分析,數據檢查點操作成本很高:需要通過數據中心的網絡連接在機器之間複製龐大的數據集,而網絡帶寬往往比內存帶寬低得多,同時還需要消耗更多的存儲資源(在內存中複製數據可以減少需要緩存的數據量,而存儲到磁盤則會拖慢應用程序)所以,我們選擇記錄更新的方式。但是,如果更新太多,那麼記錄更新成本也不低。因此,RDD只支持粗粒度轉換,即在大量記錄上執行的單個操作。將創建RDD的一系列轉換記錄下來(即Lineage),以便恢復丟失的分區

RDD詳解

  • RDD(Resilient Distributed Datasets彈性分佈式數據集),是Spark中最重要的概念,可以簡單的把RDD理解成一個提供了許多操作接口的數據集合,和一般數據集不同的是,其實際數據分佈存儲於一批機器中(內存或磁盤中)。當然,RDD肯定不會這麼簡單,它的功能還包括容錯、集合內的數據可以並行處理等。圖1是RDD類的視圖。

RDD操作類型

  • 上述例子介紹了兩種RDD的操作:filter與count;事實上,RDD還提供了許多操作方法,如map,groupByKey,reduce等操作。RDD的操作類型分爲兩類,轉換(transformations),它將根據原有的RDD創建一個新的RDD;行動(actions),對RDD操作後把結果返回給driver。例如,map是一個轉換,它把數據集中的每個元素經過一個方法處理後返回一個新的RDD;而reduce則是一個action,它收集RDD的所有數據後經過一些方法的處理,最後把結果返回給driver。

    • RDD的所有轉換操作都是lazy模式,即Spark不會立刻計算結果,而只是簡單的記住所有對數據集的轉換操作。這些轉換隻有遇到action操作的時候纔會開始計算。這樣的設計使得Spark更加的高效,例如,對一個輸入數據做一次map操作後進行reduce操作,只有reduce的結果返回給driver,而不是把數據量更大的map操作後的數據集傳遞給driver。
      下面分別是transformations和action類型的操作。

Transformations類型的操作

Action類型的操作

RDD底層實現原理

  • RDD是一個分佈式數據集,顧名思義,其數據應該分部存儲於多臺機器上。事實上,每個RDD的數據都以Block的形式存儲於多臺機器上,下圖是Spark的RDD存儲架構圖,其中每個Executor會啓動一個BlockManagerSlave,並管理一部分Block;而Block的元數據由Driver節點的BlockManagerMaster保存。BlockManagerSlave生成Block後向BlockManagerMaster註冊該Block,BlockManagerMaster管理RDD與Block的關係,當RDD不再需要存儲的時候,將向BlockManagerSlave發送指令刪除相應的Block。

RDD cache的原理

  • RDD的轉換過程中,並不是每個RDD都會存儲,如果某個RDD會被重複使用,或者計算其代價很高,那麼可以通過顯示調用RDD提供的cache()方法,把該RDD存儲下來。那RDD的cache是如何實現的呢?

RDD中提供的cache()方法只是簡單的把該RDD放到cache列表中。當RDD的iterator被調用時,通過CacheManager把RDD計算出來,並存儲到BlockManager中,下次獲取該RDD的數據時便可直接通過CacheManager從BlockManager讀出。

RDD dependency與DAG

  • RDD提供了許多轉換操作,每個轉換操作都會生成新的RDD,這是新的RDD便依賴於原有的RDD,這種RDD之間的依賴關係最終形成了DAG(Directed Acyclic Graph)。
  • RDD之間的依賴關係分爲兩種,分別是NarrowDependency與ShuffleDependency,其中ShuffleDependency爲子RDD的每個Partition都依賴於父RDD的所有Partition,而NarrowDependency則只依賴一個或部分的Partition。下圖的groupBy與join操作是ShuffleDependency,map和union是NarrowDependency。

RDD partitioner與並行度

  • 每個RDD都有Partitioner屬性,它決定了該RDD如何分區,當然Partition的個數還將決定每個Stage的Task個數。當前Spark需要應用設置Stage的並行Task個數(配置項爲:spark.default.parallelism),在未設置的情況下,子RDD會根據父RDD的Partition決定,如map操作下子RDD的Partition與父Partition完全一致,Union操作時子RDD的Partition個數爲父Partition個數之和。

如何設置spark.default.parallelism對用戶是一個挑戰,它會很大程度上決定Spark程序的性能。

發佈了251 篇原創文章 · 獲贊 66 · 訪問量 82萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章