BSP-Apache.HAMA运行过程(框架)

来源:互联网 发布:优化推广 编辑:程序博客网 时间:2024/06/01 03:58

BSP-HAMA运行过程

Hama-architecture


Apache-hama集群是以BSP为框架为基础由一个BSPMaster、(多个)互不关联的GroomServer计算结点、可独立运行的Zookpeer集群组成。BSPMaster采用“先进先出”原则对GroomServer进行监控、job的提交处理、任务的分配和记录整个的运行动态,BSPMaster调用BSP类的setup方法、bsp方法和cleanup方法对superstep进行控制。GroomServer通过“HeartBeat”向BSPMaster发送心跳信息,向BSPMaster报告当前GroomServer结点集群状态。这些状态信息包括计算结点集群的最大任务量和可用内存容量等。BSPMaster根据心跳信息启动BSP任务把job划分为一个一个的task,再把task分配给GroomServer计算结点群,GroomServer启动BSPPeer执行GroomServer分配过来的task。Zookpeer管理BSPPeers的障栅同步情况,实现BarrierSynchronisation机制。Zookpeer主要是以BSPPeer.sync()方法、enterBarrier()方法和leaveBarrier()方法控制着BSP任务的障栅同步阶段。信息的传输、接收都是在障栅同步阶段完成的。

1、job的提交和分配


图 1 job提交分配概略图

 

在GraphJob类的waitForCompetition()方法中调用submit()方法把job提交给BSPMaster,提交的主要内容是:VertexClass中的实现、VertexInputReader中的实现、Edge的属性和Vertex的ID、value等。

根据BSPMaster监控GroomServer集群的运行状态,BSPMaster对提交的job按照能运行的任务量进行对GroomServer计算结点集群分配任务。默认情况下GroomServer的运行任务量为1,如果task的运行任务量不为1,则BSPMaster分配的最大任务量为集群承受最大任务量与当前任务量的差值。根据BSPMaster分配完成的任务量对job处理的数据进行分割,数据分割完成后BSPMaster控制GroomServer把数据分配到各个BSPPeer中。

HAMA-Graph-setup和bsp运行图

Hama-Graph的运行也是遵循BSP-HAMA框架的,都是在BSP.setup()方法、BSP.bsp()方法、BSP.cleanup()方法和BSP.clear()方法中执行的。用BSP.setup()方法和BSP.cleanup()方法分别用于执行开始计算和结束计算输出计算结果。superstep的计算主要是在BSP.bsp()方法进行的,所以BSP.bsp()主要是控制着整个并行计算的核心部分。BSP.clear()方法是用于是为了清除本次的superstep的计算和准备下一步的superstep计算。


图 2 Graph运行概略图

2、数据加载和superstep初始化

数据的加载和superstep的初始化主要是通过控制着开始superstep计算的BSP.setup()方法中实现的。


图 3 数据加载概略图

分配好的数据通过BSP.setup()方法中的GraphJobRunner.loadVertices()方法把数据加载内存中。Job发布完成后用VertexInputReader.parseVertex()方法对数据进行解析,解析完成后的数据用hashMap的put(getNumPeers,GraphJobMessage)方法把数据暂时存贮在hashMap中。得到hashMap的属性(即解析后的value值)用BSPPeer.send(peerName,GraphJobMessage)方法在peers之间进行信息传递,传递的内容主要是peer的地址和GraphJobMessage信息。但是并不能保证消息的发送和接收是同一个顺序,因此在障栅同步阶段,发送的同一个信息可能会到达不能的BSPPeer上,并且BSPPeer之间又有信息的传递。等在障栅同步阶段把信息传输完成后通过MessageQueue.poll()方法BSPPeer得到传递过来的消息。

等待所有的数据加载到内存后进行superstep的初始化(整个程序只执行一次)。Superstep的初始化时通过GraphJobRunner.doInitialSuperstep()来执行的。当所有的BSPPeer接收到相应的消息后要做的工作就是对superstep计算的初始化工作,此工作被视为剧数据加载后的第一个supertep计算,虽然在此过程中有VerticeInfo.startSuperstep()方法和VerticesInfo.finishstartstep()方法运行但是没有真正得superstep计算,因为此时的顶点还是未激活的顶点,只是为了设置BSPPeer集群计算线程。

3、障栅同步

但是在障栅同步阶段的信息又是如何运作的?


图 4 障栅同步概略图

 

同步过程中信息进行传递过程中主要用到outgoingMessageManager(输出信息管理器)和localQueue(本地消息队列),通过outgoingMessageManager(输出信息管理器)把peer的地址和GraphJobMessage进行打包到outgoingBundles(输出包)中。

所有的信息都打包到outgoingBundle中后即信息的传递准备工作完成。之后所有的信息都在障栅同步阶段(sync())进行汇总。把peer的地址和GraphJobMessage信息从outgoingBundle中取出来后,通过LocalBSPRunner.tansfer()方法把储存在hashMap中的信息加载到localQueueForNextIteration(SynchronizedQueue对象)中,并用MessageQueue.addBundle()方法进行打包处理。

当信息加载到localQueue(本地消息队列)中后,所有的信息开始enterBarrier阶段。在enterBarrier阶段通过调度线程来等待(wait())其他还没有进入障栅同步阶段。当最后一个控制消息的线程进入到障栅同步阶段,并在结构中提供了一个非空的障栅屏障,则执行当前的消息线程其他消息线程依然处于等待阶段,若最后一个消息线程进入到障栅同步阶段时在结构中没有非空障栅屏障,则各个线程进入抢占模式,哪个线程抢到执行权就优先执行哪个线程。直到所有的消息线程进入障栅同步阶段才开始真正的在BSPPeer之间进行信息传递。在障栅同步阶段在BSPPeer之间进行传输是用在AbstractMessageManager.clearOutgoingMessages()方法中的localQueueForNextIteration.getMessageQueue()方法把得到的值用localQueue代换完成的。在障栅同步阶段当所有的以taskID为标识的关联的信息通过localQueue发送出去后进入到leaveBarrier阶段。

4、superstep计算



图 5 superstep概略图

 

图 6 一个superstep计算图

在一个superstep计算过程中BSPPeer只能发送消息或者处理上一个superstep中接收到的消息。

真正开始superstep计算的是在doSuperstep(GpprootraphJobMessage,BSPPeer)的方法中实现的。当BSPPeer集群开始superstep计算之前需要用类AtomitInteger激活顶点使其处于激活状态,遍历所有的信息和顶点的排列顺序,用具有相同ID的迭代信息作为第一顶点开始superstep的计算。用方法startSuperstep()执行superstep的开始,接下来时自定义compute()方法的实现,当没有激活顶点的时候或者达到自定义设置的迭代次数时表示superstep结束。

 

 

 

 

 

 

 

0 0