我正在制作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
// ...
这是广播的错误用法吗?似乎破坏了广播变量的一致性。
答案 0 :(得分:0)
每个执行者将广播从驱动程序JVM移动到执行者JVM。发生的情况是,Var
将在驱动程序上使用其当前的a
进行序列化,然后复制并反序列化到所有执行者JVM。假设get
在广播之前从未在驱动程序上调用过。现在,所有执行程序都会获得带有Var
的{{1}}的副本,每当他们调用a = 1
时,其本地JVM 中的get
的值将增加一。就是这样,其他任何事情都不会发生,并且a
的更改不会传播到任何其他执行者或驱动程序,并且a
的副本将不同步。
这是广播的错误用法吗?
好吧,有趣的问题是,为什么只传送Var
的初始值,您为什么要这样做呢?如果目标是建立具有初始初始值的 local 计数器,从技术上讲是可行的,但是有很多更清洁的方法可以实现。如果目的是让值更改返回给驱动程序,则可以,这是错误的用法,应改用accumulators。
似乎破坏了广播变量的一致性。
是的,绝对如前所述。