《Spark大数据分析实战》——3.3节GraphX

本节书摘来自华章社区《Spark大数据分析实战》一书中的第3章,第3.3节GraphX,作者高彦杰 倪亚宇,更多章节内容可以访问云栖社区“华章社区”公众号查看

3.3 GraphX
GraphX是Spark中的一个重要子项目,它利用Spark作为计算引擎,实现了大规模图计算的功能,并提供了类似Pregel的编程接口。GraphX的出现,将Spark生态系统变得更加完善和丰富;同时以其与Spark生态系统其他组件很好的融合,以及强大的图数据处理能力,在工业界得到了广泛的应用。本章主要介绍GraphX的架构、原理和使用方式。
3.3.1 GraphX简介
GraphX是常用图算法在Spark上的并行化实现,同时提供了丰富的API接口。图算法是很多复杂机器学习算法的基础,在单机环境下有很多应用案例。在大数据环境下,图的规模大到一定程度后,单机很难解决大规模的图计算,需要将算法并行化,在分布式集群上进行大规模图处理。目前,比较成熟的方案有GraphX和GraphLab等大规模图计算框架。
GraphX的特点是离线计算、批量处理,基于同步的BSP模型(Bulk Synchronous Parallel Computing Model,整体同步并行计算模型),这样的优势在于可以提升数据处理的吞吐量和规模,但是会造成速度上稍逊一筹。目前大规模图处理框架还有基于MPI模型的异步图计算模型GraphLab和同样基于BSP模型的Graph等。
现在和GraphX可以组合使用的分布式图数据库是Neo4J。Neo4J一个高性能的、非关系的、具有完全事务特性的、鲁棒的图数据库。另一个数据库是Titan,Titan是一个分布式的图形数据库,特别为存储和处理大规模图形而优化。二者均可作为GraphX的持久化层,存储大规模图数据。
3.3.2 GraphX的使用简介
类似Spark在RDD上提供了一组基本操作符(如map, f?ilter, reduce),GraphX同样也有针对Graph的基本操作符,用户可以在这些操作符传入自定义函数和通过修改图的节点属性或结构生成新的图。
GraphX提供了丰富的针对图数据的操作符。Graph类中定义了核心的、优化过的操作符。一些更加方便的由底层核心操作符组合而成的上层操作符在GraphOps中进行定义。正是通过Scala语言的implicit关键字,GraphOps中定义的操作符可以作为Graph中的成员。这样做的目的是未来GraphX会支持不同类型的图,而每种类型的图的呈现必须实现核心的操作符和复用大部分的GraphOps中实现的操作符。
下面将操作符分为几个类别进行介绍。
(1)属性操作符
表3-1给出了GraphX的属性操作符。通过属性操作符,用户可以在点或边上进行相应运算,构建和开发图算法。


《Spark大数据分析实战》——3.3节GraphX

(3)图信息属性(见表3-3)
表3-3所示为图信息属性,通过图信息属性,用户可以获取图上的统计信息。


《Spark大数据分析实战》——3.3节GraphX


《Spark大数据分析实战》——3.3节GraphX

存储和原语层:Graph类是图计算的核心类。内部含有VertexRDD、EdgeRDD和RDD[EdgeTriplet]引用。GraphImpl是Graph类的子类,实现了图操作。
接口层:在底层RDD的基础之上实现了Pregel模型,BSP模式的计算接口。
算法层:基于Pregel接口实现了常用的图算法。包括:PageRank、SVDPlusPlus、TriangleCount、ConnectedComponents、StronglyConnectedConponents等算法。
2.?存储结构
在正式的工业级的应用中,图的规模极大,上百万个节点是经常出现的。为了提高处理速度和数据量,希望能够将图以分布式的方式来存储、处理图数据。图的分布式存储大致有两种方式,边分割(Edge Cut)和点分割(Vertex Cut),如图3-16所示。最早期的图计算的框架中,使用的是Edge Cut(边分割)的存储方式。而GraphX的设计者考虑到真实世界中的大规模图大多是边多于点的图,所以采用点分割方式存储。点分割能够减少网络传输和存储开销。底层实现是将边放到各个节点存储,而在进行数据交换时将点在各个机器之间广播进行传输。对边进行分区和存储的算法主要基于PartitionStrategy中封装的分区方法。这里面的几种分区方法分别是对不同应用情景的权衡,用户可以根据具体的需求进行分区方式的选择。用户可以在程序中指定边的分区方式。例如:

val g = Graph(vertices, partitionBy(edges, PartitionStrategy.EdgePartition2D))


《Spark大数据分析实战》——3.3节GraphX

一旦边已经在集群上分区和存储,大规模并行图计算的关键挑战就变成了如何将点的属性连接到边。GraphX的处理方式是集群上移动传播点的属性数据。由于不是每个分区都需要所有的点属性(因为每个分区只是一部分边),GraphX内部维持一个路由表(routing table),这样当需要广播点到需要这个点的边的所在分区时就可以通过路由表映射,将需要的点属性传输到指定的边分区。
点分割的好处是在边的存储上是没有冗余数据的,而且对于某个点与它的邻居的交互操作,只要满足交换律和结合律。例如,求顶点的邻接顶点权重的和,可以在不同的节点进行并行运算,最后把每个节点的运行结果进行汇总,网络开销较小。代价是每个顶点属性可能要冗余存储多份,更新点数据时要有数据同步开销。
3.?使用技巧
采样观察可以通过不同的采样比例,先从小数据量进行计算、观察效果、调整参数,再逐步增加数据量进行大规模的运算。可以通过RDD的sample方法进行采样。同时通过Web UI观察集群的资源消耗。
1)内存释放:保留旧图对象的引用,但是尽快释放不使用的图的顶点属性,节省空间占用。通过unPersistVertices方法进行顶点释放。
2)GC调优,请读者参考性能调优章节介绍。
3)调试:在各个时间点可以通过graph.vertices.count()进行调试,观测图现有状态。进行问题诊断和调优。
GraphX通过提供简洁的API以及优化的图数据管理,简化了用户开发分布式图算法的复杂度。在大数据分析中更多的应用场景是进行机器学习,下面通过MLlib的介绍,读者可以了解如何通过Spark之上的MLlib进行复杂的机器学习。

上一篇:开发者云《Serverless函数计算初体验》火热上线。体验函数计算场景领取定制版马克杯


下一篇:盘点56个最实用的大数据可视化分析工具