Pregel:大规模图处理系统(待更新ing)

来源:互联网 发布:淘宝一元拍手机在哪 编辑:程序博客网 时间:2024/06/06 23:56

这篇文章是对Pregel论文思想的理解的第一部分

因为Giraph是对Pregel论文中所提到的思想的实现,即前面提到的Giraph的开发基于Pregel中的原理,所以首先要把Pregel中讲了什么搞清楚


灵感

对pregel的灵感来自于BSP模型,

  • Pregel由一系列的迭代(iterations)构成,每一次迭代我们称其为superstep
  • 每一次superstep(s)中,计算框架都会invoke用户对每个顶点定义的函数
  • 这个函数可以将 上一个superstep发来的 message读入, 进行运算,并且在下一个superstep中发送给另外的顶点,并且在此过程中修改本节点的状态和出边的状态
  • 这里值得注意的是,message通常是由顶点的出边发送

运算模式

pregel的运算模式中需要定义的如下

在Pregel 计算模式中,输入是一个有向图,该有向图的每一个顶点都有一个相应的由String 描述的vertex identifier。

每一条有向边都和其源顶点关联,并且也拥有一些用户定义的属性和值,并同时还记录了其目的顶点的ID。


典型的Pregel 计算过程如下

读取输入,初始化该图,当图被初始化好后,运行一系列的supersteps,每一次superstep 都在全局的角度上独立运行,直到整个计算结束,输出结果。


  • 在每一次的superstep 中,顶点的计算都是并行的,每一次执行用户定义的同一个函数。
  • 每个顶点可以修改其自身的状态信息或以它为起点的出边的信息,从前序superstep(s-1) 中接受message,并传送给其后续superstep(s+1),或者修改整个图的
    拓扑结构。
  • 需要注意的是,边在这种模式中不是计算的对象
  • 算法是否能够结束取决于是否所有的顶点都已经“vote”标识其自身已经达到“halt”状态了。
  • 在superstep 0,所有顶点都会被置于active 状态,每一个active 的顶点都会在计算的执行中在某一次的superstep 中被计算。顶点通过将其自身的status 设置成“halt”来表示它已经不再active。
  • 当某个顶点被设置成为halt后,表示没有进一步的计算需要进行,除非被额外的触发其他的运算(即接收到其它superstep传来的信息),而Pregel 框架将不会在接下来的superstep 中计算该顶点,除非该顶点收到一个其他superstep传送的消息
  • 如果顶点接收到message,该message 将该顶点重新置active,那么在随后的计算中该顶点必须在此deactive 其自身。
  • 综上所述,整个计算在 所有顶点都达到inactive并且没有message在传送的时候,会终止

对于每一个顶点的状态可以见下图


Pregel的输出

整个Pregel 程序的输出是所有顶点输出的集合。通常来说Pregel 程序的输出是跟输入时同构的有向图,但是并非一定是这样,因为在计算的过程中,可以对顶点和边进行添加和删除。


Pregel的信息交流方式

Pregel选择用message传递信息传递的模式,而没有用远程数据读取和其他方式共享内存的方式

这样做有两个原因。

  •   第一,messages 的传递有足够高效的表达能力,不需要远程读取(remote reads)。我们从来没有发现过在哪种图算法中消息传递不够高效的。
  •   第二是出于性能的考虑。在一个集群环境中,从远程机器上读取一个值是会有很高的延迟的,这种情况很难避免。而我们的消息传递模式通过异步和批量的方式传递消  息,可 以缓解这种远程读取的延迟。

Pregel C++ API

  • 用户覆写Vertex 类的virtual 函数Compute(),该函数会在每一次superstep中对每一个顶点进行调用。
  • 预定义的Vertex 类方法允许Compute()方法查询当前顶点的信息,其边的信息,并send message 到其他的顶点。
  • Compute()方法可以通过调用GetValue()方法来得到当前顶点的值,或者通过调用MutableValue()方法来修改当前定点的值。
  • 同时还可以通过边定义edge的迭代器来get 和set 以该顶点为起点的边对应的值。
  • 这种状态的修改时立时生效的。由于这种可见性是仅限于修改顶点的时候,所以在对不同的顶点进行并行的数据访问时不存在数据的竞争关系。
  • 顶点的值和其对应的边的值是仅有的在superstep 之间per-vertex(每个顶点)的状态。将由计算框架管理的图状态限制在一个单一的顶点值或边值的这种做法,可以使得估算计算轮次,图分布化以及错误恢复变得简单。


Pregel Message Passing

  • 顶点之间的通信是通过直接的message 传递的方式,每一个message 都包含了message 的值和目的顶点的名称。Message 值的数据类型则由用户通过Vertex类的template 参数来制定。
  • 一个顶点在一个superstep中,可以发送任意数量的message。
  • 在superstep s+1阶段, 当V调用 compute()函数的时候,通过一个迭代器,任意在superstep s阶段上,以V为终点即向V发送的信息是可见的
  • (英文原话是这样,翻译过来比较别扭,All messages sent to vertex V in superstep S are available, via an iterator, when V 's Compute() method is called in superstep S + 1.)
  • 在该迭代器中并不保证messages 的顺序,但是可以保证message 一定会被传送并且不会重复。
  • 一种通用的使用方式为:对一个顶点V,遍历其自身的出边,向每条出边发送message 到该边的目的顶点,如下图PAGERANK算法
  • 但是,dest_vertex 必须不是顶点V 的相邻顶点。一个顶点可以从当前superstep的前几次superstep 中获取其非相邻顶点的信息,或者顶点id 可以隐式的得到。
    比如,图可能是一个分团问题,有一些well-known 的顶点IDs(从V1 到Vn),这些顶点的信息,可以不用显示的包含在包含在边中。
    当任意一个message 的目标顶点不存在时,便执行用户定义的handlers,,一个handler 可以创建该不存在的顶点或从该源顶点中删除这条边。

Combiners

当一个顶点发送message,尤其是到另外一台机器的顶点时,会产生一些开销。这种情况用户可以自己想办法来缓解。比方说,假如Compute() 收到许多的int
messages,而它仅仅关心的是这些值的和,而不是每一个int 的值,这种情况下,系统可以将多个messages 合并成一个message,该message 中仅包含和的值,
这样就可以减少传输和缓存的开销。

Combiners 在默认情况下并没有被开启,这是因为要找到一种对所有顶点的compute()函数都合适的Combiner 是不可能的。而用户如果想要开启Combiner
的功能,可以继承Combiner 类,覆些其virtual 函数Combine()。框架并不会确保哪些message 会被combine 而哪些不会,也不会确保传送给Combine()的值
和combining 操作的执行顺序。所以Combiner 应该仅仅被用来减少关联和交互的开销中使用。


对于一些算法,例如单源最短路  提高了4倍通过 combiners

Pregel Aggregators

  • Pregel 的aggregator 是一种提供全局通信,监控和数据的机制。
  • 每一个顶点都可以在superstep  S 中向一个aggregator 提供一个数据,系统会使用一种聚合操作来负责聚合这些值,而产生的值将会对所有的顶点在superstep S+1 中可见
  • Pregel含有预定义的一些aggregators,min,max, or sum
  • Aggregators 可以用来做统计。例如,一个sum aggregator 可以用来统计每个顶点的出度,最后相加就为整个图的边的条数。更多复杂的类似操作可以产生一些历史统计信息。


1 0
原创粉丝点击