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