我对Spark很陌生,但已经拥有BSP模型的编程经验。在BSP模型(例如Apache Hama)中,我们必须自己处理节点的所有通信和同步。一方面哪个好,因为我们对我们想要实现的目标有了更好的控制,但另一方面它增加了更多的复杂性。
另一方面,另一方面,Spark采取所有控制并自行处理所有内容(这很棒)但我不了解内部如何工作,特别是在我们有大量数据和节点间消息传递的情况下。让我举一个例子zb = sc.broadcast(z)
r_i = x_i.map(x => Math.pow(norm(x - zb.value), 2))
r_i.checkpoint()
u_i = u_i.zip(x_i).map(ux => ux._1 + ux._2 - zb.value)
u_i.checkpoint()
x_i = f.prox(u_i.map(ui => {zb.value - ui}), rho)
x_i.checkpoint()
x = x_i.reduce(_+_) / f.numSplits.toDouble
u = u_i.reduce(_+_) / f.numSplits.toDouble
z = g.prox(x+u, f.numSplits*rho)
r = Math.sqrt(r_i.reduce(_+_))
这是一种取自here的方法,它以循环方式运行(比方说200次)。 x_i包含我们的数据(假设有100,000个条目)。
在BSP样式程序中,如果我们必须处理此映射操作,我们将对此数据进行分区并在多个节点上进行分发。每个节点将处理数据的子部分( map 操作)并将结果返回到master(在屏障同步之后)。由于主节点想要处理返回的每个单独的结果(集中主 - 见下图),我们将每个条目的结果发送给master(火花中的 reduce 运算符)。因此,( only )master在每次迭代后都会收到100,000条消息。它处理这些数据并再次将新值发送给从属服务器,然后再次开始处理下一次迭代。
现在,由于Spark从用户那里获得控制并在内部执行所有操作,我无法理解Spark在映射操作之后如何收集所有数据(异步消息传递?我听说它有p2p消息传递?地图任务之间的同步怎么样?如果它同步,那么说Spark实际上是BSP模型是对的吗?)。然后,为了应用reduce函数,它是否收集中央机器上的所有数据(如果是,它是否在一台机器上接收100,000条消息?)或者它以分布式方式减少(如果是,那么它如何才能演出?)
下图显示了master上的reduce函数。 x_i ^ k-1表示针对输入的x_i数据条目计算的 i - 值(在先前的迭代中)。 x_i ^ k表示在当前迭代中计算的x_i的值。显然,这个等式需要收集结果。
我实际上想比较两种分布式编程风格,以了解何时使用Spark以及何时转移到BSP。此外,我在互联网上看了很多,我发现map / reduce的工作原理是什么,但实际的通信/同步没什么用处。任何有用的材料都是有用的。