Spark RDD以不可變,容錯和彈性方式構建。會有什麼情況,Spark RDD無法滿足不變性?
RDD在所有情況下是否滿足不變性?或者是否有任何情況,無論是Streaming還是Core,RDD可能無法滿足不變性?
Spark RDD以不可變,容錯和彈性方式構建。會有什麼情況,Spark RDD無法滿足不變性?
RDD在所有情況下是否滿足不變性?或者是否有任何情況,無論是Streaming還是Core,RDD可能無法滿足不變性?
拿這個例子:
sc.makeRDD(1 to 100000).map(x=>{
println(x)
x + 1
}.collect
如果map
完成後一個節點發生故障,但完整的結果還沒有被髮送回驅動,然後是map
將重新計算在不同的機器上。最終結果將始終保持不變,因爲任何計算的雙倍計算值只會被返回一次。但是,對於某些呼叫,println
將發生兩次。所以,是的,DAG本身的不變性是有保證的,但是你仍然必須假設你的代碼會運行多次。
這要看你在談論RDD
時的意思。嚴格地說,RDD
只是描述了只存在於驅動程序中的血統,並沒有提供任何可用於變異血統的方法。
當處理數據時,我們不能再談論RDD,但仍然使用不可變數據結構暴露數據(斯卡拉的scala.collection.Iterator
,Python中的itertools.chain
)。
到目前爲止這麼好。不幸的是,數據結構的不變性並不意味着存儲數據的不可變性。讓我們創建一個小例子來說明:
val rdd = sc.parallelize(Array(0) :: Array(0) :: Array(0) :: Nil)
rdd.map(a => { a(0) +=1; a.head }).sum
// Double = 3.0
您可以根據需要多次執行此操作並獲得相同的結果。現在,讓我們cache
rdd
和重複整個過程:
rdd.cache
rdd.map(a => { a(0) +=1; a.head }).sum
// Double = 3.0
rdd.map(a => { a(0) +=1; a.head }).sum
// Double = 6.0
rdd.map(a => { a(0) +=1; a.head }).sum
// Double = 9.0
因爲我們在第一map
使用功能並不純,修改其參數可變取代這些變化積累了各執行和導致不可預測的輸出。例如,如果rdd
從緩存中被逐出,我們可以再次獲得3.0。如果某些分區未被緩存,則可以混合結果。
PySpark提供了更強的隔離和獲得這樣的結果是不可能的,但它是一個架構不是不變的問題。
此處帶走的信息是,在使用可變數據時應當非常小心,並且除非明確允許,否則應避免進行任何修改(fold
,aggregate
)。
不,它永遠不會失敗!如果底層基礎設施是不可變的,那麼你希望它不能滿足不變性? – eliasah
是的,我同意這個結構是不可變的。我只是想檢查是否有任何情況。它也具有彈性和容錯能力,允許在失敗時重新計算。重新計算是否也確保了不變性?考慮,在流式傳輸窗口中工作並創建一個dstream,這是一組RDD,意味着失敗和重新計算,它是否保證不變性。 – Srini