深入理解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))
     }
    )
 
 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章