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()
}
}