[OSDI 14] GraphX 基于Spark-Core下的分布式大图处理系统 学习总结

    今天要讲的文章是OSDI 2010年的一篇文章,GraphX:  Graph Processing in a Distributed Dataflow Framework。本文主要想解决的问题就是:先有的专用图处理系统能够实现广泛的系统优化,但也是有代价的。 图只是较大的分析过程的一部分,通常将非结构化的图数据和表格式数据组合在一起。 因此,分析dataflow被迫组成多个系统,这增加了复杂性并导致不必要的数据移动和重复。 此外,为了追求性能,图形处理系统通常会放弃容错,以支持快照恢复。 最后,作为专门的图处理系统,图处理框架通常不能享受分布式数据流框架的广泛支持。相比之下,通用分布式数据流框架(例如Map-Reduce [10],Spark [39],Dryad [15])暴露丰富的数据流操作符(例如map,reduce,group-by,join) 用于分析非结构化和表格化数据,并被广泛采用。 但是,直接使用数据流操作符来实现迭代图算法可能具有挑战性,往往需要复杂连接的多个阶段。 此外,分布式数据流框架中定义的通用连接和聚合策略不利用迭代图算法中的常见模式和结构,因此错过了重要的优化机会。

     为了支持这个论点,我们引入了GraphX,一个嵌入到Spark [39]分布式数据流系统中的高效的图形处理框架。

1.BackGround

    我们首先讨论一下这样一个模块化分析。这个Wikipidia 中包括各种各样的信息。我们可以提取这样的信息,网页页面连接LinkTable信息。可以得到这样的Link Table表,每一行是标题和链接信息。其次我们还可以通过每个网页和其他网页的链接表(比如某个网页可以跳转到另一个网页,这样就是一条边信息),通过这些信息我们可以构造出这样一个HyperLinks图结构。接下里我们为了统计每个网址的网页级别,也叫做网页Rank值。我们对于这样的HyperLinks图结构进行PageRank算法,最终PageRank算法收敛。其次我们还可以通过Wikipidia中的数据,构造出这样的Discussion Table。Discussion Table包括作者贡献文章。然后Editor Graph 指每篇文章的作者直接相互合作的关系,这里我们可以使用社区发现(CommunityDetection)算法用来发现网络中的社区结构,也可以视为一种广义的聚类算法。然后我们通过组合这两个应用的结果,得到Top Communities这样的表格。

        然而在这样的应用中,我们有两类不同的数据。一个是结构化的Table表格数据,另一列就是非结构化的图形数据。作者希望我们可以构建这样一个系统,既可以处理这样的结构化的表格数据,又可以处理这样的非结构化的图形数据。然而目前存在的系统对于这两中数据的处理,是隔离开来的。


        对于结构化的数据,可以通过分布式数据流系统进行处理。比如Spark以及Hadoop。然而对于非结构画的图数据,可以通过专用的分布式图系统进行处理。比如2010年 SIGMOD上发表的Pregel以及2012年 PVLDB上发表的GraphLab。

        通过这两类系统简单的组合处理这样的应用会存在很低的效率性的问题。因为它们之间存在严重的数据移动和副本开销 通过网络和本地文件系统。并且由于Hadoop MapReduce的中间结果是保存在本地磁盘中的,每次加载都要从本地磁盘中读取,效率十分低下。所以作者就提出了GraphX,GraphX通过组合结构化的Table数据和非结构化的图形数据计算。并且它能够允许单个系统能够轻松高效地支持整个数据流工作。然而有人可能会有疑问,如果我们就用分布式数据流系统处理图形数据,这个问题不就是迎刃而解了吗?


        然而研究表明如果,如果单独用分布式数据流系统去处理非结构化图形数据,性能会比专用的图处理系统很差。回过头来说,作者认为,通过识别专用图形计算中的基本数据流模式,并重新优化图处理系统中的数据流,我们可以在通用分布式数据流框架内利用专用图处理系统的优势。所以GraphX就是利用专用图处理系统中基本的数据处理模型,利用其中的一些GAS思想,来优化分布式数据流系统去处理图数据。接下来我们就来了解一下GraphX是如何进行图计算的。

2. GraphX Computing Model

2.1 GraphX Data Model       

        GraphX 为了做到将结构化的表格数据结合进来。GraphX定义了一个Property Graph 数据模型。也就是说过图数据中,每个顶点可以保存自己的顶点属性。并且图数据中每个边也可以保存自己的图形属性。这个属性可以通过不同的应用进用户自定义。


2.2 GraphX Main Idea

        它的主要思想是通过构造出这样一个Triplet 三元组视图这样的一个结构。这个结构是通过将顶点RDD和边RDD进行Join操作得到这样一个三元组信息。为什么要得到这样一个Triplet 三元组视图这样的一个结构。最主要的原因是因为这个三元组视图包括源顶点属性、目标顶点属性、以及边属性。这样我们就可以通过一些类似于专业图处理系统的GAS计算模型进行 类似MpaReduce思想的图形计算。


        它首先对每个Triplet三元组视图的每个元素进行一个MapFunction操作,得到一个消息。这个消息包括,属性数据以及一个目标顶点的ID。就是说你要将这个消息发送到哪个顶点上去。Message Combiners通过累加这些消息,然后将累加结构更新到相应顶点的属性数据。GraphX同这样一个GAS的思想,进行图形迭代计算。这个思想很像MapReduce的思想。通过这样的操作,不停的进行迭代计算。最终图形中每个顶点的属性数据收敛不再变化。整个图形算法最终完成。



2.3 Graph Program Stack


2.4 GraphX Operators


GraphX Pregel abstraction:
     它的主要思想是通过构造出这样一个Triplet 三元组视图这样的一个结构。这个结构是通过将顶点RDD和边RDD进行Join操作得到这样一个三元组信息。为什么要得到这样一个Triplet 三元组视图这样的一个结构。最主要的原因是因为这个三元组视图包括源顶点属性、目标顶点属性、以及边属性。这样我们就可以通过一些类似于专业图处理系统的GAS计算模型进行 类似MpaReduce思想的图形计算。
     它首先对每个Triplet三元组视图的每个元素进行一个MapFunction操作,得到一个消息。这个消息包括,属性数据以及一个目标顶点的ID。就是说你要将这个消息发送到哪个顶点上去。Message Combiners通过累加这些消息,然后将累加结构更新到相应顶点的属性数据。GraphX同这样一个GAS的思想,进行图形迭代计算。这个思想很像MapReduce的思想。通过这样的操作,不停的进行迭代计算。最终图形中每个顶点的属性数据收敛不再变化。整个图形算法最终完成。

3. GraphX 优化

3.1 Vertex Mirroring

     由于GraphX的顶点和边属性集合分区都是独立的,然而Join操作需要数据移动。GraphX则通过将顶点属性通过网络传输到边分区上。由于两个原因,这种方法大大减少了通信。 首先,现实世界的图通常比顶点具有更多数量级的边。 其次,单个顶点在同一个分区中可能有许多边,从而实现顶点属性的大量重用。



2.2 Multicat Join(多路广播)

        虽然所有顶点被发送到每个边缘分区的广播连接将确保连接发生在边缘分区上,但是由于大多数分区只需要一小部分顶点来完成连接,所以它仍然是低效的。 因此,GraphX引入了多播连接,其中每个顶点属性仅发送到包含相邻边的边缘分区。也就是说GraphX引入了一个Routing Table,这样一个路由表。表示的就是顶点到相应Edge 分区的映射关系,顶点被发送到所有的边缘分区时,顶点通过查看这个Routing Table,根据Routing Table得到顶点到相应Edge分区的映射关系。然后将顶点发送到相应的Edge 分区进行Join操作。


3.3 Partial Meterialization(部分实体化)

     当顶点属性改变时,顶点复制被急切地执行,但是,在边缘分区上的本地join没有实现,以避免重复。 相反,镜像顶点属性存储在每个边界分区上的散列映射中,并在构建三元组时引用。 Partial Meterialization 指的就是当图数据进行迭代计算的时候,每当顶点的属性值更新的时候,顶点Mirror更新将会被立刻执行。Master顶点的值将会发送到边分区相应的映射Hash Cache中。但是边分区上的本地join没有实现,因为为了防止程序执行错误,避免重复。

3.4 Incremental View Maintenance

        迭代图算法通常只修改每次迭代中所有顶点属性的一个子集。 因此,我们将Incremental View Maintenance应用于三元组视图,以避免不变数据的不必要移动。 在每次图数据操作之后,我们会跟踪自上次构建三元组视图后哪些顶点属性值发生了变化。 当下一次访问三元组视图时,只有已更改的顶点被重新路由到它们的边分区连接点,并且未改变的顶点的本地Mirror被重用。然后被更改的顶点更新相应的Triplets View视图。


4. mrTriplets 优化

4.1 Filtered Index Scanning

        mrTriplets操作的第一阶段就是通过扫描triplets三元组视图,然后应用用户定义的map 函数应用到每个triplets三元组中。然而随着迭代算法的进行,活跃顶点集合减少,大多数顶点已经收敛。Map function只需要操作那些活跃顶点的triplets三元组视图。直接顺序扫描所有的索引将会变得很浪费。
        为了解决这个问题 ,GraphX提出了Index Scanning对于triplets三元组视图。也就是说应用程序通过使用subgraph(计算当前图数据的子图)运算符来限制图数据来表示当前活跃顶点。活跃顶点通过route table (查询活跃顶点属于相应的edge 分区)被推送edge 分区,它可以用来使用源顶点id上的CSR索引来快速查找到相应的edge。然后活跃顶点与边数据进行Join,进而更新三元组视图。

4.2 Automatic Join Elimination

         问题:对于triplets三元组视图的某些operator访问来说,可能某些顶点属性没有访问,或则根本一个都没有使用。那么对于triplets三元组视图来说,会造成一部分资源浪费,因为mrTriplets三元组视图被构造的时候所有的source vertex属性和distinction vertex属性都被join构造到triplets视图中。

        GraphX使用JVM字节码分析器在运行时检查用户定义的函数,并确定是否引用源或目标顶点属性。如果只引用一个属性,并且三元组视图尚未实现,则GraphX自动重写生成的查询计划 三联视图从三联加入到双向联接。 如果没有引用顶点属性,则GraphX完全消除连接。 这种修改是可能的,因为三元组视图遵循Spark中RDD的惰性语义。 如果用户从不访问三元组视图,则永远不会实现。 因此,对mrTriplets的调用能够重写生成三元组视图的相关部分所需的联接。

5. Experiment

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值