是否会出现Spark RDD无法满足不变性的任何情况。

时间:2015-09-06 17:03:07

标签: apache-spark spark-streaming rdd

Spark RDD以不可变,容错和弹性的方式构建。

RDD是否满足所有情况下的不变性?或者有任何情况,无论是在流媒体还是核心,RDD可能无法满足不变性?

2 个答案:

答案 0 :(得分:4)

这取决于你谈论RDD时的意思。严格地说RDD只是对仅存在于驱动程序上的血统的描述,并且它没有提供任何可用于改变其血统的方法。

当处理数据时,我们不再谈论RDD,但是使用不可变数据结构(Scala中的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提供更强的隔离并获得结果,这是不可能的,但这是建筑问题而不是不变性。

此处带走的信息是,在处理可变数据时应格外小心并避免任何修改,除非明确允许(foldaggregate)。

答案 1 :(得分:0)

举个例子:

sc.makeRDD(1 to 100000).map(x=>{
  println(x)
  x + 1
}.collect

如果节点在map完成后失败,但尚未将完整结果发送回驱动程序,则map将在另一台计算机上重新计算。最终结果将始终相同,因为任何双倍计算的值将仅返回一次。但是,对于某些调用,println将发生两次。所以,是的,DAG本身的不变性是有保证的,但你仍然必须编写代码,假设它将运行多次。