Spark GraphX 图计算

本文深入探讨Spark GraphX的图论基础、属性图、图存储、图计算框架及其分布式模型。重点讲解GraphX如何利用点分割减少网络IO和存储空间,并介绍图构建方法、Pregel计算模型以及经典图算法如PageRank和联通分量。同时,讨论了图数据库如HugeGraph与Spark GraphX的结合应用。
摘要由CSDN通过智能技术生成

源码:https://github.com/NickyWooden/graphx-demo.git

给部门内部做的培训

1.图论基础

  • 有向图、无向图
  • 度(入度、出度)
  • DAG
  • 联通图
  • 子图

 

2.属性图

  • 定义

属性图是一个有向多图,每个顶点和边都有用户定义的对象(属性)

  • Vertex

(VertexId,顶点属性)

  • Edge

(srcVertexId,desVertexId,边属性)

 

3. 图存储

  • 边分割

沿着边切分图,同一边切成两条边分到不同的2个分区,切分边对应的顶点的副本进入其他分区

 

  • 点分割

沿着顶点切分图,两条边的公共顶点被分成两份到2个不同分区,而边只有一份副本

spark grapx为啥用点分割?

1. 减少分布式计算是的网络IO

边分割需要同步发送点属性数据,现实中总是边要远远大于顶点数,这样按边拆分会存在大量的顶点副本,都需要同步走网络IO发送顶点属性数据导致IO瓶颈

2. 减少存储空间

边切分一条边要存两次,顶点存一次;点分割是顶点存两次,边只存一次;现实世界中总是边要远远超过顶点数,所以边分割随着数据量的增加所占空间会越来越大,与点分割占空间差距越来越明显

 

  • 数据分区

spark graphx分区策略:

CanonicalRandomVertexCut, 经典的随机点分割分区,源顶点和目标顶点不区分方向进行hash分区

EdgePartition1D,源顶点Id*1125899906842597L%分区数 进行分区

 EdgePartition2D,利用生成二维矩阵进行分区

 RandomVertexCut,随机点分割分区,源顶点和目标顶点二元组进行hash分区,区分方向

要更改图分区方式,只需要调用graph.pertitionBy方法指定分区策略即可

  • 数据结构

1.VertexTable

2.EdgeTable

3.RoutingTable

负责将查找顶点属性位置并广播发送到计算节点

 

 

4. 图计算框架

  • 深度优先搜索算法(DFS)
  • 广度优先搜索算法(BFS)
  • 基于遍历(DFS/BFS)算法的:Neo4j、OrientDB、DEX和 Infinite Graph
  • 基于BSP(Bulk Synchronous Parallel Computing Model)模型,以图顶点 为中心的、基于消息传递批处理的并行引擎:GoldenOrb、Giraph、Pregel和Hama
  • Pregal图计算框架 基于BSP模型的图计算框架
  • Spark graphx就是基于BSP图计算模型实现的图计算框架,并封装了Pregal图计算框架API
  1. Spark GraphX 核心
  • 编程基础:Spark core RDD编程
  • RDD[VertexId,属性]

VertexId实际是个scala.Long类型

 

  • RDD[Edge(属性)],Edge构建时参数Edge(srcId,desId,属性)
  • RDD[EdgeTriplet]

EdgeTriplet继承自Edge并增加了源点属性和目标点属性

 

  • Graph[顶点属性,边属性],构建时参数Graph(RDD[Vertex],RDD[Edge],defaultVertex)
  • VertexRDD

继承自RDD[VertexId,属性],扩展一些独有方法,内部检索索引重用,避免进行遍历,提高计算效率

 

  • EdgeRDD

 

继承自RDD[Edge],并扩展一些独有方法,内部索引重用,避免进行遍历,提高计算效率

5.属性图构建

  • 方式一:从RDD创建

def createGraphFromRDD ={
  log("从RDD构建Graph")
  val sc = ss.sparkContext
  val users: RDD[(VertexId, (String, String))] =
    sc.parallelize(
      Array(
        (3L, ("15239871100", "陆小凤")),
        (7L, ("15287679231", "花满楼")),
        (5L, ("15287842135", "西门吹雪")),
       (2L, ("15285461279", "司空摘星"))
      ))
  // Create an RDD for edges
  val relationships: RDD[Edge[(String,String)]] =
    sc.parallelize(
      Array(
        Edge(3L, 7L, ("电话","2019-03-05 19:12:20")),
        Edge(5L, 3L, ("短信","2019-03-08 09:20:05")),
        Edge(2L, 5L, ("电话","2019-03-10 05:12:23")),
        Edge(5L, 7L, ("短信","2019-05-21 22:20:45")),
        Edge(5L, 8L, ("短信","2019-08-15 15:13:02"))
      ))
  // Define a default user in case there are relationship with missing user
  val defaultUser = ("None", "Nobody")
  // Build the initial Graph
  Graph(users, relationships, defaultUser)

}
val contactGraph = createGraphFromRDD
val triplet: RDD[EdgeTriplet[(String, String), (String, String)]] = contactGraph.triplets
triplet.collect().foreach(println)
//程序输出
((2,(15285461279,司空摘星)),(5,(15287842135,西门吹雪)),(电话,2019-03-10 05:12:23))
((3,(15239871100,陆小凤)),(7,(15287679231,花满楼)),(电话,2019-03-05 19:12:20))
((5,(15287842135,西门吹雪)),(3,(15239871100,陆小凤)),(短信,2019-03-08 09:20:05))
((5,(15287842135,西门吹雪)),(7,(15287679231,花满楼)),(短信,2019-05-21 22:20:45))
((5,(15287842135,西门吹雪)),(8,(None,Nobody)),(短信,20
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值