Spark GraphX 快速入门

简介: Spark GraphX 快速入门

0x00 教程内容


  1. Spark GraphX 理论
  2. GraphX 重要概念与实操


0x01 Spark GraphX 介绍


1. GraphX 介绍

GraphX 是 Spark 四大核心组件之一,它也是使用 Spark 作为计算引擎的,GraphX 是用于图形和图形并行计算的组件,实现了大规模图计算的功能。GraphX 的出现使 Spark 生态系统变得更加完善和丰富,同时它能够与 Spark 生态系统的其它组件天然融合,再加上它强大的图数据处理能力,在工业届得到了广泛的运用。


在高层次上,GraphX 通过引入一个新的图形抽象来扩展 Spark RDD :即顶点和边带有特性的有向多重图。GraphX 提供了一些基本运算符以及优化了的 Pregel API。 此外,GraphX 提供了大量的图算法和构建器,以简化图形分析任务。


image.png


GraphX 有两个RDD, 一个是点RDD,一个是边RDD。

Vertex:表示顶点,每个顶点都会有一个唯一标识以及这个顶点的属性 。

Edge:表示有向边,由一个源顶点id,一个目标顶点id以及这条边的属性组成 。


这些关系,都可以转化为相应的表来描述。


2. GraphX 的使用场景

在社交网络中,比如:Twitter、Facebook、微博、微信等,人与人之间存在着很多的关系链。这些地方产生的数据更加适合使用图处理来进行计算。图的分布式或者并行处理其实是把图拆分成很多个子图,然后分别对这些子图进行计算,计算的时候可以分别迭代进行分阶段的计算,即对图进行并行计算。


0x02 GraphX 重要概念与实操


1. 属性图

属性图是一个有向多重图,它的每个顶点和每条边都附有用户定义的对象。作为有向图,有向多重图可能有多个平行的边来共享相同的源顶点和目标顶点。作为多重图,它支持并行边,这个特性简化了许多涉及多重关系的建模场景。每个顶点的主键是一个长度为64 bit的唯一标识符(VertexID)。GraphX没有为顶点添加任何顺序的约束。类似地,每一条边有对应的源顶点和目标顶点的标识符。


因此,属性图的参数是通过顶点(VD)和边的类型(ED)来决定的。


在某些情况下,你可能希望在同一个图里面,顶点能够有不同的属性类型。这个想法可以通过继承实现。举个例子,我们可以对用户和产品进行建模,将其作为一个二分图,然后进行如下的定义:


class VertexProperty()
case class UserProperty(val name: String) extends VertexProperty
case class ProductProperty(val name: String, val price: Double) extends VertexProperty
// 图可能会有这个类型
var graph: Graph[VertexProperty, String] = null


类似于 RDD,属性图是不可变的、分布式的,并且具有容错性。对于图而言,它的值或者结构上的改变,是通过产生带有预期改变的新图来完成的。主要注意的是,原始图的主要部分(即不受影响的结构、属性和索引等)在新图中被重用,以减少固有功能的数据结构成本。通过使用大量的启发式顶点分区,图在不同的执行器里被划分。就像 RDD 一样,图的每个分区可以在发生故障时被不同的机器重建。


属性图在逻辑上对应于一对类型化集合(RDD),该集合编码了每个顶点和每条边属性。因而,图类包含了可以访问图的顶点和边的成员,它的定义如下:


class Graph[VD, ED] {
  val vertices: VertexRDD[VD]
  val edges: EdgeRDD[ED]
}


VertexRDD[VD]类和EdgeRDD[ED]类分别继承和优化了RDD[(VertexID, VD)]类和RDD[Edge[ED]]类。两者都提供基于图计算和内部优化构建的额外功能。在此你可将其简单地理解为以RDD[(VertexID, VD)]和RDD[Edge[ED]]形式定义的 RDD。


2. 多种方式理解GraphX

a. EdgeTriplet表示


val facts: RDD[String] = graph.triplets.map(triplet => triplet.srcAttr._1 + " is the " + triplet.attr + " of " + triplet.dstAttr._1)


b. SQL表示triplet表示

SELECT src.id, dst.id, src.attr, e.attr, dst.attr 
FROM edges AS e LEFT JOIN vertices AS src, vertices AS dst 
ON e.srcId = src.Id AND e.dstId = dst.Id


c. 图表示triplet表示

image.png


3. 属性图编程示例

现在假设我们要构建一个由许多来自 GraphX 项目组的协作者组成的属性图。顶点的属性可能包含用户名职业。我们应该用一个可以描述协作者间的关系的字符串来注释图的边。依然是使用上面的图:


微信图片_20220619172524.png


启动Spark Shell:

spark-shell


编写案例代码:

import org.apache.spark.graphx.{Edge, Graph, VertexId}
import org.apache.spark.rdd.RDD
// 如果不是在 `spark-shell` 中操作,则还需要额外引入 `SparkContext`。
// val sc: SparkContext
// 创建一个RDD用于表示顶点
val users: RDD[(VertexId, (String, String))] =
  sc.parallelize(Array((3L, ("xiaoshao", "student")), (7L, ("laoshao", "Postdoctoral")),
    (5L, ("laonai", "professor")), (2L, ("laoyi", "professor"))))
// 创建一个RDD用于表示边
val relationships: RDD[Edge[String]] =
  sc.parallelize(Array(Edge(3L, 7L, "partner"),
    Edge(5L, 3L, "mentor"),Edge(2L, 5L, "worker"), Edge(5L, 7L, "leader")))
// 定义默认的用户,用于建立与缺失的用户之间的关系
val defaultUser = ("spark", "default")
// 构造图对象,即初始化
val graph = Graph(users, relationships, defaultUser)


Edge类有srcIddstId,分别对应于源顶点目标顶点的标识符。另外,Edge类有一个名为attr的成员,用于存储边的属性,可以结合着表来理解。

执行过程如图:


微信图片_20220619172549.png


我们可以进一步操作,使用graph.verticesgraph.edges函数来解构一个图,将其转化为各个顶点和边的视图,并且实现一些简单的统计操作:

// 看看博士后的有多少人
graph.vertices.filter { case (id, (name, pos)) => pos == "Postdoctoral" }.count


image.png

// 源顶点id大于目标顶点id的数量
graph.edges.filter(e => e.srcId > e.dstId).count


image.png


// 显示关系
val facts: RDD[String] = graph.triplets.map(triplet =>
  triplet.srcAttr._1 + " is the " + triplet.attr + " of " + triplet.dstAttr._1)
facts.collect.foreach(println(_))


image.png


解释:graph.vertices函数的返回值类型是 VertexRDD[(String, String)],它继承了 RDD[(VertexID, (String, String))],所以我们可以用 Scala 的 case 表达式来解构这个元组。另外,graph.edges函数的返回值类型是EdgeRDD,它包含了Edge[String]对象。


0xFF 总结


  1. 更多学习请参考官网:https://spark.apache.org/docs/latest/graphx-programming-guide.html
  2. 推荐一本入门GraphX的入门书籍:《Spark GraphX实战》,挺适合初学者入门。


相关文章
|
4月前
|
设计模式 SQL 分布式计算
Spark Day06:Spark Core之Spark 内核调度和SparkSQL快速入门
Spark Day06:Spark Core之Spark 内核调度和SparkSQL快速入门
43 0
|
7月前
|
SQL 分布式计算 大数据
大数据Spark SQL快速入门
大数据Spark SQL快速入门
88 0
|
消息中间件 分布式计算 网络协议
Spark Streaming 快速入门(实操)
Spark Streaming 快速入门(实操)
325 0
Spark Streaming 快速入门(实操)
|
SQL JSON 分布式计算
Spark SQL快速入门(基础)
Spark SQL快速入门(基础)
435 0
Spark SQL快速入门(基础)
|
5月前
|
分布式计算 Java Spark
图解Spark Graphx实现顶点关联邻接顶点的collectNeighbors函数原理
图解Spark Graphx实现顶点关联邻接顶点的collectNeighbors函数原理
34 0
|
7月前
|
分布式计算 监控 大数据
大数据Spark快速入门
大数据Spark快速入门
93 0
|
3月前
|
分布式计算 算法 数据挖掘
Spark中的图计算库GraphX是什么?请解释其作用和常用操作。
Spark中的图计算库GraphX是什么?请解释其作用和常用操作。
33 1
|
4月前
|
分布式计算 Hadoop Java
Spark_Day01:Spark 框架概述和Spark 快速入门
Spark_Day01:Spark 框架概述和Spark 快速入门
51 0
|
12月前
|
存储 分布式计算 Scala
Spark快速入门-3-Spark的算子总结
Transformation 变换/转换算子:这类算子操作是延迟计算的,也就是说从一个RDD 转换生成另一个 RDD 的转换操作不是马上执行,需要等到有 Action 操作的时候才会真正触发运算。这种变换并不触发提交作业,完成作业中间过程处理。 Action 行动算子:这类算子会触发 SparkContext 提交 Job 作业,并将数据输出 Spark 系统。
|
12月前
|
存储 分布式计算 Hadoop
Spark快速入门-2-Spark的编程模型
Spark快速入门-2-Spark的编程模型