我是Apache Spark的新手,我正在使用GraphX。所以我必须使用Scala,我也是新的; - )。
已更新
我有一张图表,让我们说如下图所示:
每个节点都有自己的HashMap或List,可以存储ID。现在我正在迭代图的三元组,如果edge属性匹配一个条件(在这个例子中被忽略),那么我想在这个边的起始和结束节点中存储相同的ID。
在该算法的一轮之后,结果可能如下所示:
这里的代码(缩写):
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进行并行计算时使用的变量被复制到工人/线程,这不应该发生在这里。
提前致谢!
答案 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
你也可以使用边缘归属
来做到这一点