Spark review diez: operaciones de agregación de gráficos (agreggateMessages) y API de Pregel y Pregel y análisis de casos de operaciones

1. Operación de agregación de gráficos agregateMessages

1.1 Operación de agregación:

agreggateMessages: un paso clave en muchas tareas de análisis de gráficos es agregar la información de vecindad de cada vértice,

La operación de agregación central en GraphX ​​es agregateMessages. Su función principal es enviar mensajes a los vecinos y fusionar los mensajes recibidos por los vecinos.

1.2. SendMsg y mergeMsg  :

sendMsg:
La función sendMsg toma EdgeContext como parámetro de entrada y no tiene valor de retorno
EdgeContext proporciona dos funciones de envío de mensajes
sendToSrc: envía mensajes de tipo Msg al vértice de origen
sendToDst: envía mensajes de tipo Msg al vértice de destino
mergeMsg   :
Todos los mensajes recibidos por cada vértice se agregarán y pasarán a la función mergeMsg
La función mergeMsg define cómo convertir todos los mensajes recibidos por el vértice en los resultados que necesitamos
 

3. Demostración de la operación de agregación de la figura:

package aggregate

import org.apache.spark.{SparkConf, SparkContext}
import org.apache.spark.graphx.{Edge, EdgeContext, Graph}

object aggreTest2 {

  def sendMsg(ec:EdgeContext[Int,String,Int]):Unit = {
    ec.sendToDst( ec.srcAttr +1)
  }

  def mergeMsg(a: Int , b:Int) :Int = {
    math.max(a,b)
  }

  def sumEdgeCount( g:Graph[Int,String]):Graph[Int,String] = {
    val verts = g.aggregateMessages[Int]( sendMsg , mergeMsg)

    //verts.collect.foreach(println(_))

    val g2 = Graph(verts ,g.edges)


   //(4,(1,0))
    println( "*************************************")
    //g2.vertices.join(g.vertices).map( x => x._2._1 - x._2._2).reduce(_+_).collect.foreach(println(_))
    val check = g2.vertices.join(g.vertices).map( x => x._2._1 - x._2._2).reduce(_+_)
    println(check)
    println( "*************************************")
    if(check > 0)
      sumEdgeCount(g2)
    else
      g
  }



  def main(args: Array[String]): Unit = {

    //设置运行环境
    val conf = new SparkConf().setAppName("SimpleGraphX").setMaster("local")
    val sc = new SparkContext(conf)
    sc.setLogLevel("WARN")

    // 构建图
    val myVertices = sc.parallelize(Array((1L, "张三"), (2L, "李四"), (3L, "王五"), (4L, "钱六"),
      (5L, "领导")))
    val myEdges = sc.makeRDD(Array( Edge(1L,2L,"朋友"),
      Edge(2L,3L,"朋友") , Edge(3L,4L,"朋友"),
      Edge(4L,5L,"上下级"),Edge(3L,5L,"上下级")
    ))

    val myGraph = Graph(myVertices,myEdges)

    val initGraph = myGraph.mapVertices((_,_)=>0)

     sumEdgeCount(initGraph).vertices.collect.foreach(println(_))



  }

}

2. API de Pregel:

2.1 Pregel 和Pregel API:

Pregel
Después del surgimiento de Hadoop, Google lanzó tres trabajos de investigación, que elaboraron respectivamente tres tecnologías de cafeína, Pregel y Dremel, estas tres tecnologías también se han convertido en la nueva "troika" de Google, que Pregel fue propuesta por Google Utilizado para el marco de computación gráfica distribuida a gran escala. La figura principalmente para desplazamiento (BFS), ruta más corta (la SSSP ), el cálculo PageRank se calcula y similares .
API de Pregel :
Los gráficos son esencialmente estructuras de datos recursivas porque los atributos de los vértices dependen de los atributos de sus vecinos, que a su vez dependen de los atributos de sus vecinos. Por lo tanto, muchos algoritmos gráficos importantes recalculan iterativamente los atributos de cada vértice hasta que se alcanza una condición de punto fijo. Se propone una serie de abstracciones paralelas gráficas para expresar estos algoritmos iterativos. GraphX implementa su propia API Pregel de acuerdo con las ideas de Google
 

 2 0,2 mayor BSP paralelo síncrono:

Genere un mensaje y páselo al siguiente paso superior. Hasta el final de la actual super-paso y todos los mensajes que se pasan al siguiente paso después de la súper , el siguiente paso será un comienzo estupendo . Esta es la barrera de sincronización .

2.3 Pregel API completa los detalles internos de un súper paso:

2.4 función de pregel :

2. El parámetro activeDirection de 5 p regel:

Para los dos vértices srcId y dstId de un borde:
            EdgeDirection. Out: cuando srcId recibe un mensaje de la iteración anterior, llamará a sendMsg, lo que significa que este borde se considera como el "borde exterior" de srcId.
            EdgeDirection. In-Cuando dstId recibe un mensaje de la iteración anterior, llamará a sendMsg, lo que significa que este borde se considera como el "borde entrante" de dstId.
           EdgeDirection. O bien: siempre que srcId o dstId reciban un mensaje de la iteración anterior, se llamará a sendMsg.
EdgeDirection. Ambos: solo cuando srcId y dstId reciben el mensaje de la iteración anterior, se llamará a sendMsg.

2.6 Caso de pregel:

package pregel

import org.apache.spark.{SparkConf, SparkContext}
import org.apache.spark.graphx.{Edge, Graph, VertexId}
import org.apache.spark.graphx.util.GraphGenerators

object GraphXTest1 {

  def main(args: Array[String]): Unit = {
    //设置运行环境
    val conf = new SparkConf().setAppName("Pregel API GraphX").setMaster("local")
    val sc = new SparkContext(conf)
    sc.setLogLevel("WARN")

    // 构建图
    val myVertices = sc.parallelize(Array((1L, 0), (2L, 0), (3L, 0), (4L, 0),
      (5L, 0)))
    val myEdges = sc.makeRDD(Array( Edge(1L,2L,2.5),
      Edge(2L,3L,3.6) , Edge(3L,4L,4.5),
      Edge(4L,5L,0.1),Edge(3L,5L,5.2)
    ))
    val myGraph = Graph(myVertices,myEdges)

    val sourceId: VertexId = 1L // The ultimate source
    // Initialize the graph such that all vertices except the root have distance infinity.
    val initialGraph = myGraph.mapVertices((id, _) =>
      if (id == sourceId) 0.0 else Double.PositiveInfinity)


    val sssp: Graph[Double, Double] = initialGraph.pregel(Double.PositiveInfinity)(
      (id, dist, newDist) => math.min(dist, newDist), // Vertex Program
      triplet => {  // Send Message
        if (triplet.srcAttr + triplet.attr < triplet.dstAttr) {
          Iterator((triplet.dstId, triplet.srcAttr + triplet.attr))
        } else {
          Iterator.empty
        }
      },
      (a, b) => math.min(a, b) // Merge Message
    )

    sssp.vertices.collect.foreach(println(_))
  }


}

 

28 artículos originales publicados · Me gustaron 54 · Visitas 1103

Supongo que te gusta

Origin blog.csdn.net/csdnliu123/article/details/105622013
Recomendado
Clasificación