访问不可变广播变量的可变属性

时间:2019-06-12 04:03:43

标签: apache-spark

我正在制作Spark App,但卡在广播变量上。根据文档,广播变量应为“只读”。如果它的属性是可变的怎么办?

在本地,它像变量一样工作。我没有集群环境,所以...

case object Var {
   private var a = 1
   def get() = {
       a = a + 1
       a
   }
}

val b = sc.broadcast(Var)

// usage 
b.value.get   // => 2
b.value.get   // => 3
// ...

这是广播的错误用法吗?似乎破坏了广播变量的一致性。

1 个答案:

答案 0 :(得分:0)

每个执行者将广播从驱动程序JVM移动到执行者JVM。发生的情况是,Var将在驱动程序上使用其当前的a进行序列化,然后复制并反序列化到所有执行者JVM。假设get在广播之前从未在驱动程序上调用过。现在,所有执行程序都会获得带有Var的{​​{1}}的副本,每当他们调用a = 1时,其本地JVM 中的get的值将增加一。就是这样,其他任何事情都不会发生,并且a的更改不会传播到任何其他执行者或驱动程序,并且a的副本将不同步。

  

这是广播的错误用法吗?

好吧,有趣的问题是,为什么只传送Var的初始值,您为什么要这样做呢?如果目标是建立具有初始初始值的 local 计数器,从技术上讲是可行的,但是有很多更清洁的方法可以实现。如果目的是让值更改返回给驱动程序,则可以,这是错误的用法,应改用accumulators

  

似乎破坏了广播变量的一致性。

是的,绝对如前所述。