Spark GraphX原理介绍

背景

现实应用中,数据内部可能存在较高的关联度,如图模型应用。在对这样的数据进行处理时,并行计算框架就会面临较大的挑战,会引入大量的数据连接(join)和聚合(aggregation)操作,带来大量的计算和数据迁移,严重消耗集群资源,因此对此类算法的优化就显得极为重要。
互联网上网页权值计算的PageRank算法是一个典型的图模型问题,它依据网页之间的链接指向关系来判断网页的重要性,指向一个网页的链接数越多,相应的网页就越重要。PageRank算法可用图模型来处理,如图 3 (a)所示,图中顶点代表互联网上的网页,有向边代表网页之间的链接指向关系。PageRank算法首先进行网页权值的初始化,如图 3 (b)所示。接下来PageRank算法进行图迭代过程,迭代分为两步:
第一步,根据顶点权值生成边的权值,如图 3(c)所示。边的权值计算公式如下:
这里写图片描述
第二步,根据顶点权值和边的权值计算顶点新的权值,如图 3(d)所示,计算公式如下:

PageRank算法不断重复执行图的迭代过程,直至顶点的权值不再发生变化,各顶点的最终权值便是网页的重要性得分。
Spark GraphX原理介绍_第1张图片
图计算框架针对图数据结构的特点,对数据进行更好的组织,充分挖掘图结构的特点,优化计算框架以达到较好的分布式计算性能。在目前的大数据环境下,大部分图计算框架对图的数据进行分布式存储,在图结构上进行数据的计算、传输和更新操作。通过操作图顶点的数据及与顶点相连的边上的数据,产生发送给与其相连的顶点的消息,消息通过网络或其他方式传输给指定顶点,顶点在收到消息或状态后进行更新,生成新的图数据。

GraphX简介

GraphX是构建在Spark之上的图计算框架,它使用RDD来存储图数据,并提供了实用的图操作方法。由于RDD的与生俱来的特性,GraphX高效地实现了图的分布式存储和处理,可以应用于社交网络等大规模的图计算场景。GraphX在图顶点信息和边信息存储上做了优化,使得图计算框架性能相对于原生RDD实现得以较大提升,接近或到达GraphLab等专业图计算平台的性能。GraphX最大的贡献是,在Spark之上提供一栈式数据解决方案,可以方便且高效地完成图计算的一整套流水作业。
众所周知,图结构中最基本的要素是顶点和边。GraphX描述的是拥有顶点属性和边属性的有向图。GraphX提供顶点(Vertex)、边(Edge)、边三元组(EdgeTriplet)三种视图。GraphX的各种图操作也是在这三种视图上完成的。如图 4所示,顶点包含顶点ID和顶点数据(VD);边包含源顶点ID(srcId)、目的顶点ID(dstId)和边数据(ED)。边三元组是边的扩展,它在边的基础上提供了边的源顶点数据、目的顶点数据。在许多图计算操作中,需要将边数据以及边所连接的顶点数据一起组成边三元组,然后在边三元组上进行操作。

GraphX分布式存储

GraphX将图数据以RDD分布式地存储在集群的节点上,使用顶点RDD(VertexRDD)、边RDD(EdgeRDD)存储顶点集合和边集合。
顶点RDD通过按顶点的ID进行哈希分区,将顶点数据以多分区形式分布在集群上。边RDD按指定的分区策略(Partition Strategy)进行分区(默认使用边的srcId进行哈希分区),将边数据以多分区形式分布在集群上。另外,顶点RDD中还拥有顶点到边RDD分区的路由信息——路由表。路由表存在顶点RDD的分区中,它记录分区内顶点跟所有边RDD分区的关系。在边RDD需要顶点数据时(如构造边三元组),顶点RDD会根据路由表把顶点数据发送至边RDD分区。如图 5所示,按顶点分割方法将图分解后得到顶点RDD、边RDD和路由表(注意,此处RDD未按分区函数分区)。
Spark GraphX原理介绍_第2张图片
在图计算过程中,有些边的计算需要顶点数据,即需形成边三元组视图,如PageRank算法生出边的权值,这需要将顶点的权值发送至出边所在的边RDD分区。GraphX依据路由表,从顶点RDD中生成与边RDD分区相对应的重复顶点视图(ReplicatedVertexView),它的作用是作为中间RDD,将顶点数据传送至边RDD分区。重复顶点视图按边RDD分区并携带顶点数据的RDD,如图 6所示,顶点分区A中便携带边RDD分区A中的所有的顶点,它与边RDD中的顶点是co-partition(即分区个数相同,且分区方法相同)。在图计算时,GraphX将重复顶点视图和边RDD进行拉链(zipPartition)操作,即将重复顶点视图和边RDD的分区一一对应地组合起来,从而将边与顶点数据连接起来,使边分区拥有顶点数据。整个形成边三元组过程,只有在顶点RDD形成重复顶点视图中存在分区间数据移动,拉链操作不需要移动顶点数据和边数据。由于顶点数据一般比边数据要少的多,而且随着迭代次数的增加,需要更新的顶点数目也越来越少,重复顶点视图中携带的顶点数据也相应减少,这样就可以大大减少数据的移动量,加快执行速度。
GraphX在顶点RDD和边RDD的分区中以数组形式存储顶点数据和边数据,目的是为了不损失元素访问性能。GraphX在分区里建立了众多索引结构,高效地实现快速访问顶点数据或边数据。在迭代过程中,图的结构不会发生变化,因而顶点RDD、边RDD以及重复顶点视图中的索引结构全部可以重用,当由一个图生成另一个图时,只须更新顶点RDD和RDD的数据存储数组。索引结构的重用,是GraphX保持高性能的关键,也是相对于原生RDD实现图模型性能能够大幅提高的主要原因。
Spark GraphX原理介绍_第3张图片

GraphX功能简介

GraphX对Spark RDD进行了封装,用类来表示图模型,它提供了一些基础的图操作方法。除此之外,GraphX还实现了一些常用的图算法模型,如相邻顶点收集算法、图中三角形统计算法、PageRank算法、pregel图计算框架等等。GraphX提供的这些基础的图操作方法和现成的图算法模型使得用户在Spark上编写图应用程序变得非常容易。
这里介绍一些重要的GraphX图操作方法。
1. mapEdges
返回按用户提供函数改变图中边数据的值或类型之后的图。
2. mapVertices
返回按用户提供函数改变图中顶点数据的值或类型之后的图。
3. outerJoinVertices
返回依据用户提供的顶点数据和函数改变图中顶点数据的值或类型之后的图。
4. mask
返回和另外一个图公共顶点和边组成的图。
5. subgraph
返回按用户提供函数进行顶点和边过滤的图。
6. aggregateMessages
aggregateMessages是GraphX最重要的图操作方法,它主要用来高效解决相邻边或相邻顶点之间的通信问题,如:将与顶点相邻的边或顶点的数据聚集在顶点上、将顶点数据散发在相邻边上。aggregateMessages方法能够简单、高效地解决PageRank等图迭代应用。

aggregateMessages在逻辑上分为三步:(1)由边三元组生成消息;(2)向边三元组的顶点发送消息;(3)顶点聚合收到的消息。它实现分为map阶段和reduce阶段。

1) aggregateMessages map
GraphX使用顶点RDD更新重复顶点视图。重复顶点视图与边RDD进行分区拉链(zipPartitions)操作,将顶点数据传往边RDD分区,实现边三元组视图。
对边RDD进行map操作,依据用户提供的函数为每个边三元组产生一个消息(Msg),生成以顶点ID、消息为元素的RDD,其类型为RDD[(VertexId, Msg)]。
2) aggregateMessages reduce
reduce阶段首先对1)中的消息RDD按顶点分区方式进行分区(使用顶点RDD的分区函数),分区后的消息RDD与该图的顶点RDD元素分布状况将完全相同。在分区时,GraphX会使用用户提供的聚合函数合并相同顶点的消息,最终形成类似顶点RDD的消息RDD。
应用程序中,一般会用消息RDD数据更新Graph对象的顶点RDD,进行下一轮迭代。

作者介绍

唐黎哲,国防科学技术大学 并行与分布式计算国家重点实验室(PDL)硕士,从事spark、图计算、LDA(主题分类)研究,欢迎交流,请多指教。
邮箱:[email protected]

你可能感兴趣的:(spark,GraphX,图计算)