关键词 Spark GraphX RDD Edge EdgeRDD EdgeRDDImpl 分区 索引 分区索引
本文介绍Spark GraphX内部对边存储的机理,详解边分区内部的索引构建过程。
在最初,边是这样的 RDD[(srcId, dstId, attr)],这种记法要看得懂,简而言之,它是(srcId, dstId, attr)这个三元组的集合。不过,RDD进行了分区存储,分区内部元素使用数组形式存储。这种结构并不能提供有效的图计算,如快速找出(srcId, dstId)的属性值attr,找出以srcId为源顶点的所有边等操作若按遍历方式处理,效率将非常低。
这里有一些对象要理解:
Edge,边对象,存有srcId, dstId, attr 3个字段,和一点点边的方法
RDD[Edge],存放着Edge对象的RDD
EdgeRDD,完整提供边的各种操作类,编程时用的就是它了。
EdgeRDDImpl,边的一些分区优化实现类,把边优化存储在分区里。这是GraphX 内部的类了,编程时都不用它的,我们调用EdgeRDD就行了。
它们之间继承关系如下:
EdgeRDD extends RDD[Edge]
EdgeRDDImpl extends EdgeRDD
于是乎,GraphX是这样处理的…
构建RDD[Edge]
调用RDD[(srcId, dstId, attr)]的map操作,把(srcId, dstId, attr)转为Edge,这里就不介绍了,只是调用map算子而已
由RDD[Edge]构建EdgeRDD
EdgeRDD.fromEdges(edges:RDD[Edge]):EdgeRDDImpl,这个初始化方法实现了我们的转换,我们接下来看一看它是如何实现的
def fromEdges[ED: ClassTag, VD: ClassTag](edges: RDD[Edge[ED]]): EdgeRDDImpl[ED, VD] = {
val edgePartitions = edges.mapPartitionsWithIndex { (pid, iter) =>