GraphX
Spark GraphX 是一个分布式图处理框架,它是基于 Spark 平台提供对图计算和图挖掘简洁易用的而丰富的接口,极大的方便了对分布式图处理的需求。
图的分布式或者并行处理其实是把图拆分成很多的子图,然后分别对这些子图进行计算,计算的时候可以分别迭代进行分阶段的计算,即对图进行并行计算。
GraphX 的核心抽象是 Resilient Distributed Property Graph,一种点和边都带属性的有向多重图。它扩展了Spark RDD 的抽象,有 Table 和 Graph 两种视图 ,而只需要 一份物理存储 (Vertex Table 和 Edege Table)。 两种视图都有自己独有的 API ,从而获得了灵活操作和执行效率。
Table 视图
Table 视图将图看成 Vertex Property Table 和 Edge Property Table 等的组合,这些 Table 继承了 Spark RDD 的 API(fiter,map等)。
Table 视图除了顶点和边视图,还包含三元组视图,三元组视图是在边视图的基础上,加上了源顶点和目的顶点的属性。
对 Graph 视图的所有操作,最终都会转换成其关联的 Table 视图的 RDD 操作来完成。这样对一个图的计算,最终在逻辑上,等价于一系列 RDD 的转换过程。
Graph 视图
Graph 视图包括 reverse/subgraph/mapV(E)/joinV(E)/mrTriplets 等操作。结合 pagerank 和社交网络的实例看看mrTriplets(最复杂的一个API )的用法。
存储模式
巨型图的存储总体上有 边分割 和 点分割 两种存储方式:
-
边分割(Edge-Cut):每个顶点都存储一次,但有的边会被打断分到两台机器上。这样做的好处是节省存储空间;坏处是对图进行基于边的计算时,对于一条两个顶点被分到不同机器上的边来说,要跨机器通信传输数据,内网通信流量大。
-
点分割(Vertex-Cut):每条边只存储一次,都只会出现在一台机器上。邻居多的点会被复制到多台机器上,增加了存储开销,同时会引发数据同步问题。好处是可以大幅减少内网通信量。
虽然两种方法互有利弊,但现在是点分割占上风,各种分布式图计算框架都将自己底层的存储形式变成了点分割。主要原因有以下两个:
-
磁盘价格下降,存储空间不再是问题,而内网的通信资源没有突破性进展,集群计算时内网带宽是宝贵的,时间比磁盘更珍贵。这点就类似于常见的空间换时间的策略。
-
在当前的应用场景中,绝大多数网络都是“无尺度网络”,遵循幂律分布,不同点的邻居数量相差非常悬殊。而边分割会使那些多邻居的点所相连的边大多数被分到不同的机器上,这样的数据分布会使得内网带宽更加捉襟见肘,于是边分割存储方式被渐渐抛弃了。
因此,Graphx 使用的也是 Vertex-Cut(点分割)方式存储图,用三个RDD存储图数据信息:
-
VertexTable(id, data):id 为 Vertex id,data 为 Edge data;
-
EdgeTable(pid, src, dst, data):pid 为 Partion id,src 为源顶点 id,dst 为目的顶点 id;
-
RoutingTable(id, pid):id 为 Vertex id,pid 为 Partion id。
参考资料
[1] https://spark.apache.org/docs/latest/graphx-programming-guide.html