Pregel的体系结构
一、Pregel的执行过程
1、在Pregel计算框架中,一个大型图会被划分成许多个分区,每个分区都包含了一部分顶点以及以这些顶点为起点的边
2、一个顶点应该被分配到哪个分区上,是由一个函数决定的,系统默认函数为hash(ID) mod N,其中,N为所有分区总数,ID是这个顶点的标识符;当然,用户也可以自己定义这个函数
3、这样,无论在哪台机器上,都可以简单根据顶点ID判断出该顶点属于哪个分区,即使该顶点可能已经不存在了

每个工作服务器收到的子图中,可能有部分顶点和边是需要其他规则服务器处理的;此时该工作服务器把不属于自己处理的顶点和边发生给对应的工作服务器(每个工作服务器都知道整个图的分区情况,即知道哪些顶点哪些边由哪些工作服务器处理)。
在理想的情况下(不发生任何错误),一个Pregel用户程序的执行过程如下:
(1)选择集群中的多台机器执行图计算任务,每台机器上运行用户程序的一个副本,其中,有一台机器会被选为Master,其他机器作为Worker。Master只负责协调多个Worker执行任务,系统不会把图的任何分区分配给它。Worker借助于名称服务系统可以定位到Master的位置,并向Master发送自己的注册信息。
(2)Master把一个图分成多个分区,并把分区分配到多个Worker。一个Worker会领到一个或多个分区,每个Worker知道所有其他Worker所分配到的分区情况。每个Worker负责维护分配给自己的那些分区的状态(顶点及边的增删),对分配给自己的分区中的顶点执行Compute()函数,向外发送消息,并管理接收到的消息。
(3)Master会把用户输入划分成多个部分,通常是基于文件边界进行划分。划分后,每个部分都是一系列记录的集合,每条记录都包含一定数量的顶点和边。然后,Master会为每个Worker分配用户输入的一部分(输入的图数据分给多个Worker来加载处理)。如果一个Worker从输入内容中加载到的顶点,刚好是自己所分配到的分区中的顶点,就会立即更新相应的数据结构。否则,该Worker会根据加载到的顶点的ID,把它发送到其所属的分区所在的Worker上(每个Worker都知道其他Worker的分区情况,即知道哪些节点哪些边由哪个Worker来处理)。当所有的输入都被加载后,图中的所有顶点都会被标记为“活跃”状态。
(4)Master向每个Worker发送指令,Worker收到指令后,开始运行一个超步。Worker会为自己管辖的每个分区分配一个线程,对于分区中的每个顶点,Worker会把来自上一个超步的、发给该顶点的消息传递给它,并调用处于“活跃”状态的顶点上的Compute()函数,在执行计算过程中,顶点可以对外发送消息,但是,所有消息的发送工作必须在本超步结束之前完成。当所有这些工作都完成以后,Worker会通知Master,并把自己在下一个超步还处于“活跃”状态的顶点的数量报告给Master。上述步骤会被不断重复,直到所有顶点都不再活跃并且系统中不会有任何消息在传输,这时,执行过程才会结束。
(5)计算过程结束后,Master会给所有的Worker发送指令,通知每个Worker对自己的计算结果进行持久化存储。

二、容错性
1、Pregel采用检查点机制来实现容错。在每个超步的开始,Master会通知所有的Worker把自己管辖的分区的状态(包括顶点值、边值以及接收到的消息),写入到持久化存储设备(用于Worker故障后其他Worker读取故障前计算结果继续执行剩余超步计算任务)
2、Master会周期性地向每个Worker发送ping消息,Worker收到ping消息后会给Master发送反馈消息。如果Master在指定时间间隔内没有收到某个Worker的反馈消息,就会把该Worker标记为“失效”。同样地,如果一个Worker在指定的时间间隔内没有收到来自Master的ping消息,该Worker也会停止工作
3、每个Worker上都保存了一个或多个分区的状态信息,当一个Worker发生故障时,它所负责维护的分区的当前状态信息就会丢失。Master监测到一个Worker发生故障“失效”后,会把失效Worker所分配到的分区,重新分配到其他处于正常工作状态的Worker集合上,然后,所有这些分区会从最近的某超步S开始时写出的检查点中,重新加载状态信息
三、Worker工作服务器
在一个Worker中,它所管辖的分区的状态信息是保存在内存中的(检查点机制时才会持久化)。分区中的顶点的状态信息包括:
1、顶点的当前值
2、以该顶点为起点的出射边列表,每条出射边包含了目标顶点ID和边的值
3、消息队列,包含了所有接收到的、发送给该顶点的消息
4、标志位,用来标记顶点是否处于活跃状态
在每个超步中,Worker会对自己所管辖的分区中的每个顶点进行遍历,并调用顶点上的Compute()函数,在调用时,会把以下三个参数传递进去:
1、该顶点的当前值
2、一个接收到的消息的迭代器
3、一个出射边的迭代器(本超步完成后要沿着本顶点的所有出射边发生消息给其他目标顶点)
在Pregel中,为了获得更好的性能,“标志位”和输入消息队列是分开保存的:
1、对于每个顶点而言,Pregel只保存一份顶点值和边值,但是,会保存两份“标志位”和输入消息队列,分别用于当前超步和下一个超步
2、在超步S中,当一个Worker在进行顶点处理时,用于当前超步的消息会被处理,同时,它在处理过程中还会接收到来自其他Worker的消息,这些消息会在下一个超步S+1中被处理,因此,需要两个消息队列用于存放作用于当前超步S的消息和作用于下一个超步S+1的消息
3、如果一个顶点V在超步S接收到消息,那么,它表示V将会在下一个超步S+1中(而不是当前超步S中)处于“活跃”状态
顶点间消息发送机制:
1、当一个Worker上的一个顶点V需要发送消息到其他顶点U时,该Worker会首先判断目标顶点U是否位于自己机器上
2、如果目标顶点U在自己的机器上,就直接把消息放入到与目标顶点U对应的输入消息队列中(一个Worker多个分区多个线程)
3、如果发现目标顶点U在远程机器上,这个消息就会被暂时缓存到本地,当缓存中的消息数目达到一个事先设定的阈值时,这些缓存消息会被批量异步发送出去,传输到目标顶点所在的Worker上
4、如果存在用户自定义的Combiner操作,那么,当消息被加入到输出队列或者到达输入队列时,就可以对消息执行合并操作,这样可以节省存储空间和网络传输开销
四、Master
Master主要负责协调各个Worker执行任务,每个Worker会借助于名称服务系统定位到Master的位置,并向Master发送自己的注册信息,Master会为每个Worker分配一个唯一的ID
Master维护着关于当前处于“有效”状态的所有Worker的各种信息,包括每个Worker的ID和地址信息,以及每个Worker被分配到的分区信息
虽然在集群中只有一个Master,但是,它仍然能够承担起一个大规模图计算的协调任务,这是因为Master中保存这些信息的数据结构的大小,只与分区的数量有关,而与顶点和边的数量无关
一个大规模图计算任务会被Master分解到多个Worker去执行,在每个超步开始时,Master都会向所有处于“有效”状态的Worker发送相同的指令,然后等待这些Worker的回应
如果在指定时间内收不到某个Worker的反馈,Master就认为这个Worker失效
如果参与任务执行的多个Worker中的任意一个发生了故障失效,Master就会进入恢复模式
在每个超步中,图计算的各种工作,比如输入、输出、计算、保存和从检查点中恢复,都会在“路障(barrier)”之前(超步同步后可能发生检查点,每个Worker保存各自顶点的信息)结束
如果路障同步成功,说明一个超步顺利结束,Master就会进入下一个处理阶段,图计算进入下一个超步的执行
Master在内部运行了一个HTTP服务器来显示图计算过程的各种信息
用户可以通过网页随时监控图计算执行过程各个细节
图的大小
关于出度分布的柱状图
处于活跃状态的顶点数量
在当前超步的时间信息和消息流量
所有用户自定义Aggregator的值
五、Aggregator聚合规约----对一个值集合进行聚合计算得到一个全局值
每个用户自定义的Aggregator都会采用聚合函数对一个值集合进行聚合计算得到一个全局值
每个Worker都保存了一个Aggregator的实例集,其中的每个实例都是由类型名称和实例名称来标识的
在执行图计算过程的某个超步S中,每个Worker会利用一个Aggregator对当前本地分区中包含的所有顶点的值进行归约,得到一个本地的局部归约值
在超步S结束时,所有Worker会将所有包含局部归约值的Aggregator的值进行最后的汇总,得到全局值,然后提交给Master
在下一个超步S+1开始时,Master就会将Aggregator的全局值发送给每个Worker
浙公网安备 33010602011771号