为什么需要图计算
- 许多大数据以大规模图或网络的形式呈现
- 许多非图结构的大数据,常会被转换为图模型进行分析
- 图数据结构很好地表达了数据之间的关联性
图(Graph)的基本概念
图是由顶点集合(vertex)及顶点间的关系集合(边edge)组成的一种网状数据结构。通常表示为二元组:Gragh=(V,E)
,可以对事物之间的关系建模。一般应用于在地图应用中寻找最短路径、社交网络关系、网页间超链接关系。
图的术语
顶点和边
Graph=(V,E)
集合V={v1,v2,v3}
集合E={(v1,v2),(v1,v3),(v2,v3)}
有向图
G=(V,E)
V={A,B,C,D,E}
E={<A,B>,<B,C>,<B,D>,<C,E>,<D,A>,<E,D>}
无向图
G=(V,E)
V={A,B,C,D,E}
E={(A,B),(A,D),(B,C),(B,D),(C,E),(D,E)}
有环图
包含一系列顶点连接的回路(环路)
无环图
DAG即为有向无环图
度
一个顶点所有边的数量
- 出度:指从当前顶点指向其他顶点的边的数量
- 入度:其他顶点指向当前顶点的边的数量
邻接矩阵
1、对于每条边,矩阵中相应单元格值为1
2、对于每个循环,矩阵中相应单元格值为2,方便在行或列上求得顶点度数
Spark GraphX
GraphX是Spark提供分布式图计算API
GraphX特点:
1、基于内存实现了数据的复用与快速读取
2、通过弹性分布式属性图(Property Graph)统一了图视图与表视图
3、与Spark Streaming、Spark SQL和Spark MLlib等无缝衔接
GraphX核心抽象:
弹性分布式属性图(Resilient Distributed Property Graph):
顶点和边都带属性的有向多重图;
一份物理存储,两种视图:对Graph视图的所有操作,最终都会转换成其关联的Table视图的RDD操作来完成
创建Graph
Graph[VD,ED]
VertexRDD[VD]
EdgeRDD[ED]
EdgeTriplet[VD,ED]
Edge:样例类
VertexId:Long的别名
//e.txt
1,2,同学
2,3,同事
//v.txt
1,张三,30
2,李四,40
3,王五,20
object MyGraphx01 {
def main(args: Array[String]): Unit = {
//读所有的点和图
val spark = SparkSession.builder().appName("myghp01").master("local[*]").getOrCreate()
val vects = spark.sparkContext.textFile("src/main/resources/graph01/v.txt")
val eds = spark.sparkContext.textFile("src/main/resources/graph01/e.txt")
//所有的点构成1个seq((L1,users),(L2,users))
val allVects = vects.map(line=>{
var arr = line.split(",");
val key = arr(0).toString.toLong;
(key,Users(key,arr(1).toString(),arr(2).toString().toInt))
}).cache()
//将所有的边数据变成Seq((1L,2L,同学),(L2,L3,同事))
val allEdges = eds.map(lien=>{
var Array(one,two,triship) = lien.split(",");//模式匹配
Edge(one.toLong,two.toLong,triship)
}).cache()
//将所有的点边构成图
val graph = Graph(allVects,allEdges).cache()
spark.stop()
}
}
查看图信息:
val numEdges: Long//边的数量
val numVertices: Long//点的数量
val inDegrees: VertexRDD[Int]//入度数
val outDegrees: VertexRDD[Int]//出度数
val degrees: VertexRDD[Int]//总度
graph.triplets相关函数:
//src是出发点(key->srcid,value->srcAttr),dst是终点,attr是权重
srcAttr
dstAttr
srcId
dstId
attr