Apache Spark共享计数器

时间:2014-08-07 09:35:18

标签: scala apache-spark

我是Apache Spark的新手,我正在使用GraphX。所以我必须使用Scala,我也是新的; - )。

已更新

我有一张图表,让我们说如下图所示:

Example graph

每个节点都有自己的HashMap或List,可以存储ID。现在我正在迭代图的三元组,如果edge属性匹配一个条件(在这个例子中被忽略),那么我想在这个边的起始​​和结束节点中存储相同的ID。

在该算法的一轮之后,结果可能如下所示:

After one round

这里的代码(缩写):

val newNodes = graph.triplets.flatMap(triplet => {
    val newId = Counter.getId();
    val map = List((srcId, newId), (dstId, newId))
    // Outputs sth. like
    //  (1, 1)   (3, 1)   (2, 2)    (3, 2)
}

我从计数器对象中获取唯一ID:

object Counter{
    private var resultCount: Integer = 0;

    def getResultID(): Integer = {
        resultCount = resultCount + 1;
        return resultCount;
    }
}

在flatMap之后,我按节点id对所有元组进行分组,然后将一个节点的所有id放在一个列表中(使用map-operator)。所以结果是节点3:(3,List(1,2))。然后使用outerJoin将该结果存储回图形。

所以我的问题是,我是否必须关心,通过同步方法ID是唯一的还是以这种方式可以吗?如果有人通过解决整个问题有另一个想法而没有给出明确的ID例如zip-Method,那么这也很好: - )。

除了这个问题,有人可以解释一下,在运行期间对Counter对象发生了什么?因为它是一个单例,它是否存在于执行驱动程序的某个地方(在Master上?),因为我读到某处,你可以在普通代码中使用然后在与Spark进行并行计算时使用的变量被复制到工人/线程,这不应该发生在这里。

提前致谢!

1 个答案:

答案 0 :(得分:4)

没有必要自己实现这一点,分配唯一ID是如此常见,以至于已经在def zipWithUniqueId(): RDD[(T, Long)]中内置了spark,因为你可以看到它为每个值分配了一个唯一的long,这意味着它返回一个RDD元组。用法示例:

val uniqIds = vertexData.zipWithUniqueId().map((k,v)=>(v,k)) //I'm assuming you want the unique ids as the vertexId

你也可以使用边缘归属

来做到这一点