spark 系列
Spark GraphX中的pregel API
Spark GraphX pregel
前言
在上一篇博客已经为大家介绍了Spark GraphX图计算中的PageRank 算法。本篇博客将为大家详细介绍了 Spark GraphX中常用的函数pregel实现最短路径或者最小值的实现原理和方式。
pregel API
概述
图本质上是一种递归的数据结构,其顶点的属性值依赖于其邻接顶点,而其邻接顶点属性又依赖于其邻接顶点,许多重要的图算法通过迭代计算每个顶点的属性直到到达定点条件,这些迭代的图算法被抽象成一系列图并行操作。
Pregel是Google提出的用于大规模分布式图计算框架,常用来解决一下问题:
- 图遍历(BFS)
- 单源最短路径(SSSP)
- PageRank计算(上一篇已经介绍过)
Pregel的计算由一系列迭代组成,称为supersteps。Pregel迭代过程(实现过程)如下:
- 每个顶点从上一个superstep接收入站消息
- 计算顶点新的属性值
- 在下一个superstep中向相邻的顶点发送消息
- 当没有剩余消息时,迭代结束
源码参数分析
源码
def pregel[A: ClassTag](
initialMsg: A,
maxIterations: Int = Int.MaxValue,
activeDirection: EdgeDirection = EdgeDirection.Either)(
vprog: (VertexId, VD, A) => VD,
sendMsg: EdgeTriplet[VD, ED] => Iterator[(VertexId, A)],
mergeMsg: (A, A) => A)
: Graph[VD, ED] = {
Pregel(graph, initialMsg, maxIterations, activeDirection)(vprog, sendMsg, mergeMsg)
}
相关参数
相关参数 | 说明 |
---|---|
VD | 顶点的数据类型 |
ED | 边的数据类型 |
A | Pregel message的类型 |
graph | 输入的图 |
参数
参数 | 说明 |
---|---|
initialMsg | 图初始化的时候,开始模型计算的时候,所有节点都会先收到一个消息 |
maxIterations | 最大迭代次数 |
activeDirection | 规定了发送消息的方向(默认是出边方向:EdgeDirection.Out) |
vprog | 节点接收该消息并将聚合后的数据和本节点进行属性的合并 |
sendMsg | 激活态的节点调用该方法发送消息 |
mergeMsg | 如果一个节点接收到多条消息,先用mergeMsg 来将多条消息聚合成为一条消息,如果节点只收到一条消息,则不调用该函数 |
关联常用GraphX 的API
常用GraphX 的API | 说明 |
---|---|
mapReduceTriplets() | 计算每个节点的相邻的边缘和顶点的值,用户定义的mapFunc函数会在图的每一条边调用,产生0或者多个message发送到这条边两个顶点其中一个当中,reduceFunc函数用来合并map阶段的输出到每个节点 |
案例
在理解案例之前,首先要清楚关于 顶点 的两点知识:
顶点 的状态有两种:
- 钝化态【类似于休眠,不做任何事】
- 激活态【干活】
顶点 能够处于激活态需要满足以下任意条件:
- 成功收到消息
- 成功发送了任何一条消息
案例一:求最短距离
顶点5到其他各顶点的最短距离 实现代码:
object Test{
def main(args: Array[String]): Unit = {
//1、创建SparkContext
val sparkConf = new SparkConf().setAppName("GraphxHelloWorld").setMaster("local[*]")
val sparkContext = new SparkContext(sparkConf)
//2、创建顶点
val vertexArray = Array(
(1L, ("Alice"