1. 程式人生 > >spark RDD的5個重要內部屬性

spark RDD的5個重要內部屬性

RDDs 介面的五個屬性
下表總結了 RDDs 的五個屬性:

上述屬性可以概括為幾個方面:一組分割槽,表示資料集包含的分片;一組依賴關係,指向其父 RDD;一個函式,基於父 RDD 進行計算;以及劃分策略和資料位置相關的元資料。

例如上文中的程式碼例項裡,HDFS 檔案作為輸入,初始 RDD 的 partitions 代表檔案中每個檔案塊的分割槽(包含檔案塊在每個分割槽物件中的偏移量),preferredLocations 表示檔案塊所在的節點,而 iterator 可以用來讀取這些檔案塊。在一個 RDD 上呼叫 map 操作時,會返回一個 MappedRDD 物件,這個物件與其父物件具有相同的分割槽以及 preferredLocations,但在其 iterator 中,傳遞給 map 的匿名函式會應用到父物件中的資料。

RDDs 依賴關係
在 Spark 中,RDD 之間的依賴關係分為兩類:

1.窄依賴:每個父 RDD 的分割槽都至多被一個子 RDD 的分割槽使用,即為 OneToOneDependecies;
2.寬依賴:多個子 RDD 的分割槽依賴一個父 RDD 的分割槽,即為 OneToManyDependecies。

例如,map 操作是一種窄依賴,而 join 操作是一種寬依賴(除非父 RDDs 已經基於 Hash 策略被精心劃分過了)。

窄依賴和寬依賴的區別在 Spark 開發中很重要。

首先,窄依賴允許在單個叢集節點上對一個數據分片進行流水線式操作,這個節點可以直接訪問所有依賴的父級分割槽。例如,可以逐個元素地依次執行 filter 操作和 map 操作。相反,寬依賴需要所有的父 RDD 資料可用,並且資料已經通過類 MapReduce 中的 shuffle 操作完成了聚合。

其次,在窄依賴中,節點失敗後的恢復更加高效。因為只有直接依賴的父級分割槽需要重新計算,並且這些父級分割槽可以並行地在不同節點上重新計算。相反,在寬依賴的繼承關係中,單個失敗的節點可能導致一個 RDD 的所有祖先 RDD 重算,從而導致大量計算的重新執行。不過,進行寬依賴類的操作(比如 shuffle 依賴)時,Spark 會將中間結果儲存到父分割槽所在的節點上。這和 MapReduce 本地儲存 Map 的輸出類似,能簡化資料的故障恢復過程。

檢查點支援 (Checkpoint)
雖然 lineage 可用於出現錯誤後 RDD 的恢復,但對於 lineage 很長的 RDD 來說,從源頭恢復耗時可能較長。因此,將某些 RDD 進行檢查點操作 (Checkpoint),使之儲存到穩定的儲存上,對錯誤情況下的 RDD 重算是有幫助的。

通常情況下,對於包含寬依賴的長血統 RDD 設定檢查點操作是非常有用的,因為寬依賴條件下,此類 RDD 失效會使得 Spark 從各個父 RDD 上重新取得資料進行恢復,且節點失效很有可能影響到寬依賴 RDD 的父節點,重算開銷較大。相反,對於那些窄依賴於穩定儲存上資料的 RDD 來說,對其進行檢查點操作就不是很有必要,如果一個節點發生故障,RDD 在該節點中丟失的分割槽資料可以通過並行的方式從其他節點中重新計算出來,計算成本只是整個 RDD 的很小一部分。

Spark 當前提供了為 RDD 設定檢查點(用一個 REPLICATE 標誌來持久化)操作的 API,讓使用者自行決定需要為哪些資料設定檢查點操作。