深入理解graphx中的pregel图计算引擎

深入理解graphx中的pregel图计算引擎

一、graphx中的属性
(1)顶点(vertex),顶点包含(id,顶点内容)两部分,其中顶点内容可以是对象或者元组形式
对象形式:User("name", 12)
元组形式:("name", 12)
(2)边(edge),包含(srcid, dstid, 边属性),边属性目前使用过程中都是Int或者Double单值形式
(3)三元组(triplets),它是边的扩展,包含(源顶点,边,目标顶点),可以灵活取到顶点的属性信息。
 
二、pregel参数说明
def pregel[A: ClassTag](
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] = {
Pregel(graph, initialMsg, maxIterations, activeDirection)(vprog, sendMsg, mergeMsg)
}
 
配上运作流程图如下:

 
1、在pregel中顶点有两种状态:活跃状态(active)和不活跃状态(halt)。如果某一个顶点接收到了消息并且需要执行计算那么它就会将自己设置为活跃状态。如果没有接收到消息或者接收到消息,但是发现自己不需要进行计算,那么就会将自己设置为不活跃状态。
pregel运行的第一步是给所有顶点发送消息,使其处于活跃状态,发送的初始消息即为参数initialMsg。
2、maxIterations表示迭代的最大次数,activeDirection表示消息发送的方向,该值为EdgeDirection类型,这是一个枚举类型,有三个可能值:EdgeDirection.In/ EdgeDirection.Out/ EdgeDirection.Either.可以看到,第二和第三个参数都有默认值。
3、vprog是顶点端的操作,它需要处理的是根据顶点已有的内容信息和接收到的message消息的汇总,其中message消息是mergeMsg操作的结果。比如上图中的顶点1,第一次需要处理的是初始消息(initialMsg)和顶点1本身内容的汇总。顶点3在完成初始化之后,需要处理顶点1和顶点2发送过来的消息,消息内容汇总完之后再与顶点3本身的内容进行汇总。
4、sendMsg是向相邻顶点发送消息,这个过程是一种map操作。发送的消息可以是多种形式的,与顶点内容的结构无关。比如顶点内容的结构是(权重,出度数,最短距离数),而发送消息的内容结构可以是(权重信息,边信息),在vprog操作时可以把顶点的"权重"和消息的"权重信息"进行计算,"最短距离数"和"边信息"进行计算,计算出新的(权重,出度数,最短距离数)值
5、mergeMsg是在目标顶点进行所有接收到的消息(message)的汇总,这个过程是一种reduce操作。
 
三、实例说明
1、顶点结构为:id, (weight, outdegree, distance)
2、边的结构为:Edge(srcid, dstid, distance)
3、消息的结构为:weight, distance
4、代码,功能是最短距离计算和pagerank概率计算的结合,其中:
(1)outDegreesGraph是上述说明的顶点结构和边结构组成的图
(2)triplet.srcAttr._1 * 1.0 / triplet.srcAttr._2是把 顶点权重/出度数 得到的值发送给相邻顶点
(3)triplet.srcAttr._3 + triplet.attr是把距离信息发送给相邻顶点
(4)判断triplet.srcAttr._3 + triplet.attr < triplet.dstAttr._3是只有满足当前路径+边值小于目标顶点的距离时,才去更新目标顶点的距离信息。
(5)triplet.srcAttr._3 < MAX_DISTANCE,尽早结束计算
(6)x._1 + y._1, math.min(x._2, y._2):所有message权重信息相加,所有message取距离最小值
 
    val firstMessage = (0.0, Double.PositiveInfinity) // weight, distance初始发送消息
    val MAX_DISTANCE = 4 // 最大的最短路径
    val influenceGraph = outDegreesGraph.pregel(firstMessage)(
      (vId, vData, msgSum) =>
       (vData._1 + msgSum._1, vData._2, math.min(vData._3, msgSum._2)),
     triplet => {
       if(triplet.srcAttr._3 + triplet.attr < triplet.dstAttr._3  && triplet.srcAttr._3 < MAX_DISTANCE){
         Iterator((triplet.dstId, (triplet.srcAttr._1 * 1.0 / triplet.srcAttr._2, triplet.srcAttr._3 + triplet.attr)))
       }else{
         Iterator.empty
       }
     },
      (x, y) => {
       (x._1 + y._1, math.min(x._2, y._2))
     }
    )
 
 

猜你喜欢

转载自blog.csdn.net/fly_time2012/article/details/105739042
今日推荐