Pregel in GraphX
上周看到GraphX lib里面自带的ShortestPaths.scala用的框架为Pregel,于是这周我首先看了Pregel在GraphX上的实现。在读代码的过程中,我顺便过了一下部分GraphX的API。
def apply[VD: ClassTag, ED: ClassTag, A: ClassTag]
(graph: Graph[VD, ED],
initialMsg: A,
maxIterations: Int = Int.MaxValue,
activeDirection: EdgeDirection = EdgeDirection.Either)
(vprog: (VertexId, VD, A) => VD,
sendMsg: EdgeTriplet[VD, ED] => Iterator[(VertexId, A)],
mergeMsg: (A, A) => A)
: Graph[VD, ED] =
{
//这句代码是说,用initialMsg来初始化程序,生成新的graph,新graph的结构与原graph相同,不同的是,vertex的属性发生了变化。
var g = graph.mapVertices((vid, vdata) => vprog(vid, vdata, initialMsg)).cache()
/*
mapReduceTriplets()接受一个mapFunc sendMsg和一个reduceFunc mergeMsg,mapFunc会在所有edge上被invoke,返回值为一个(VertexId, A)类型的迭代器,代表需要发送给srcVertex或dstVertex的信息。而reduceFunc来处理这些信息。
*/
var messages = g.mapReduceTriplets(sendMsg, mergeMsg)
var activeMessages = messages.count()
var prevG: Graph[VD, ED] = null
var i = 0
while (activeMessages > 0 && i < maxIterations) {
/*innerJoin函数会接受两个参数,一个是需要参与innerJoin的RDD,另一个是对匹配项的操作函数,在ShortestPath中,相当于对于任意点V,在已经merge的message中,找到与之匹配某个点,然后对它们的距离进行比较,取较小的作为新的值。
*/
val newVerts = g.vertices.innerJoin(messages)(vprog).cache()
prevG = g
/*与innerJoin类似,outerJoin也是接受两个参数,mapFunc判断是否有新的值产生,如果有,则返回新的值,否则返回旧值
*/
g = g.outerJoinVertices(newVerts) { (vid, old, newOpt) => newOpt.getOrElse(old) }