SparkGraphX的简单讲解

1.SparkGraphX的官方文档连接

http://spark.apachecn.org/docs/cn/2.2.0/graphx-programming-guide.html

2.添加maven依赖

<!-- https://mvnrepository.com/artifact/org.apache.spark/spark-graphx_2.11 -->
<dependency>
    <groupId>org.apache.spark</groupId>
    <artifactId>spark-graphx_2.11</artifactId>
    <version>2.3.0</version>
</dependency>

3.图计算详解


图就是计算机的一种数据结构

图计算是建立在RDD之上的

第一个例子:

package com.dmp.test.GraphTest

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

/**
  * SparkGraphX的简单实用
  */
object GraphTest {
  def main(args: Array[String]): Unit = {
    val conf = new SparkConf()
    conf.setAppName("GraphTest")
    conf.setMaster("local")
    val sc = new SparkContext(conf)
    //构建顶点 返回的这个Long其实是VertexId类型,都是一样的
    val users: RDD[(Long, (String, String))] = sc.parallelize(Array((3L, ("rxin", "student")), (7L, ("jgonzal", "postdoc")),
      (5L, ("franklin", "prof")), (2L, ("istoica", "prof"))))
    //构建边 (边有个独特的类Edge,某种程度讲代表的就是一些关系)
    val relationships: RDD[Edge[String]] = sc.parallelize(Array(Edge(3L, 7L, "collab"), Edge(5L, 3L, "advisor"),
      Edge(2L, 5L, "colleague"), Edge(5L, 7L, "pi")))

    //顶点和边    这样就构建了我们的图
    val graph = Graph(users, relationships)
    // .vertices获取到这个图中所有的顶点
    val count = graph.vertices.filter {
      case (id, (name, pos)) => {
        //计算我们这个图中有多少个postdoc博士后
        pos == "postdoc"
      }
    }.count()
    // 1
    println(count)
    //.edges获取到这个图中所有的边,过滤出 源ID>目标ID 的数量
    val count1 = graph.edges.filter(e => e.srcId > e.dstId).count()
    // 1
    println(count1)

    sc.stop()
  }

}

4.图的组成

G(P)=(V,E,P)

其中的V代表的是顶点的意思 Vertex

其中的E代表的是边 Edge

其中的P代表的是property(在顶点里面有属性,在边里面也有这个属性)

5.图的数据结构的组成

顶点(Vertex)



边(Edge)



边三元组(EdgeTriplet)


下面的SQL说的就是边三元组:


6.图的存储

边分割



顶点分割




7.官网案例示范

followers.txt中的数据:


users.txt中的数据:


package com.dmp.test.GraphTest

import org.apache.spark.graphx.GraphLoader
import org.apache.spark.{SparkConf, SparkContext}

/**
  * 图计算官网案例示范
  * 主要解决项目中遇到的 把同一个用户识别出来,如果是同一个用户就合并到一起
  */
object ConnectedComponentsExample {
  def main(args: Array[String]): Unit = {
    //graphx 基于RDD
    val conf = new SparkConf()
    conf.setMaster("local")
    conf.setAppName("ConnectedComponentsExample")
    val sc = new SparkContext(conf)

    //构建出来图有多种方式
    val grapxh = GraphLoader.edgeListFile(sc, "G:\\workspace\\1711dmp\\src\\main\\scala\\com\\dmp\\test\\GraphTest\\followers.txt")
    grapxh.vertices.foreach(println(_))
    /** 就是把所有的数字作为key,value都写为1
      * (4,1)
      * (1,1)
      * (6,1)
      * (3,1)
      * (7,1)
      * (5,1)
      * (2,1)
      */
    /**
      * .connectedComponents()计算每个顶点的连接组件成员,并返回带有顶点的图形
      * 包含该顶点的连通组件中包含最低顶点id的值。
      */
    val cc = grapxh.connectedComponents().vertices
    cc.foreach(println(_))
    /**
      * value是这一组中最小的数,是好友的value是一样的
      * (4,4)
      * (6,4)
      * (7,4)
      *
      * (1,1)
      * (3,1)
      * (5,1)
      * (2,1)
      *
      */
    val users = sc.textFile("G:\\workspace\\1711dmp\\src\\main\\scala\\com\\dmp\\test\\GraphTest\\users.txt").map(line => {
      //以为要join,所以要变成kv形式
      val fields = line.split(",")
      (fields(0).toLong, fields(1))
    })

    //(1,刘德华)  join  (1,1)
    //(1,(刘德华,1) 代表的是同一个好友的那个id
    users.join(cc).map {
      case (id, (username, cclastid)) => (cclastid, username)
    }.reduceByKey((x: String, y: String) => x + "," + y)
      .foreach(tuple => {
        println(tuple._2)
      })

    /**
      *
      * 郭富城,小马,小张
      * 刘德华,黎明,小李,张学友
      *
      */

    sc.stop()
  }

}


猜你喜欢

转载自blog.csdn.net/jenrey/article/details/80513456