Scala值不存储在spark中

时间:2016-03-24 07:47:59

标签: scala apache-spark

var cnt = 0
val newRDD = oldRDD.map({ list =>
        ...some work
        cnt = cnt + 1
        println(cnt) // print 1, 2, 3.. well
        newList // will store in new RDD
    })

//out side of map
println(cnt) // It's 0. Why?

作为日志,首先打印地图内部,然后打印出地图的一面。为什么不存储cnt值?

3 个答案:

答案 0 :(得分:4)

Spark变换应该是纯函数 - 接收输入,产生输出,没有改变状态或具有任何副作用。你的例子违反了这些。

这里发生的是:

  • 作为参数传递给map的匿名函数序列化并发送给工作人员
  • cnt的初始值用它序列化
  • cnt在每个工作人员反序列化时为0
  • 现在,每个工作人员在本地增加cnt
  • 那...... 驱动程序应用程序中的cnt值保持不变

作为替代方案,您可以使用Spark的Accumulators来实现这些类型的"计数器"。

答案 1 :(得分:2)

在Spark框架中,当您在闭包中使用外部变量时,它会自动发送到工作节点。每个任务都获得一个变量的新副本,但是如果你更新任务中的变量(这就是你的代码会发生什么),框架就不会发回它并将它与程序的其余部分同步,因为它也是这样做很贵。

如果您在闭包中使用外部变量,则可以将其视为只读变量。

如果你要计算你映射的元素数量,你可以首先使用oldRDD.count() / newRDD.count()(因为看起来你没有过滤元素,它应该给出相同的结果)。

答案 2 :(得分:1)

我认为你应该首先检查一下,以了解Spark中的共享变量:http://spark.apache.org/docs/latest/programming-guide.html#shared-variables