Hama框架学习(三) Master如何将job规划到GroomServer

来源:互联网 发布:淘宝买台式机 编辑:程序博客网 时间:2024/05/09 12:10
*作者:王连平*如有转载,请注明文章出处:http://blog.csdn.net/wlp001007/article/details/47423533*本文章距离上一篇文章间隔了很长一段时间,很不好意思,这是因为最近一直在忙一个Giraph项目,没来得及写,废话不多说,直接切入主题吧。上一篇文章中,已经介绍了master如何将一个job规划,转换成task,存入一个名为WAIT_QUEUE的队列中去,而且也提到了“生产与消费者”模式,截止上篇文章,其实已经将生产者讲解完了,下面就是消费者的部分。这个部分其实比较简单,下面一步步来分析。首先,我们从最开始的BSPMaster的启动说起,在启动服务时,实际上消费者已经产生。话说,BSPMaster是在BSPMasterRunner这个类的main方法中启动的,下面是它的代码:

这里写图片描述
上面代码中可以看到,BSPMaster这个对象是通过BSPMaster类的静态方法startMaster这个方法获得的,因此,我们首先来看下这个方法:
这里写图片描述
上面的代码中,有一个很重要的对象taskScheduler,这个对象并不陌生,前面的文章中已经提到过,想要说的是taskScheduler . start(),这个方法的调用,其实就是消费者的启动,接下来看在这个方法中究竟做了哪些事情:
这里写图片描述
如上代码中,可以看到,在这个方法中,taskScheduler的主要任务是: 设置queueManager、创建“WAI T_QUEUE”“PROCESSING_QUEUE”“FINISHED_QUEUE”三个队列、添加监听器、启动job处理程序…看到这是不是有点恍然大悟了,在前面的文章中我们提到了,job在提交时,basmaster将它规划并放入WAI T_QUEUE队列中去了,那个队列就是在这创建的,那么真正的消费者到底在哪呢?对,就在jobProcessor.start()这个方法中,该方法具体如下:
这里写图片描述
这里要说明的一点就是,JobProcessor是个继承了Thread的类,因此调用start方法其实就是启动了一个线程,此时该线程的运行函数如上图所示。在上面这个函数中,我们可以看到有个while循环,该循环中,首先从queueManager处得到了WAIT_QUEUE这个队列,然后从该队列中得到一个job,将该job添加到PROCESSING_QUEUE队列中(相当于换了个位置),紧接着得到groomserver的列表list,最后规划该job。先不说规划的细节,我们从这个方法中实际上已经看到了“消费”这个动作,因此,生产与消费者模式实际上已经完成了。当然,对于如何消费的细节,这还没有完,下面我们将进入schedule中看一下具体是怎么规划的。
这里写图片描述
从上面的代码,我们可以清晰的看到规划的细节,划红线的那行代码,实际上是得到一个规划结果,具体规划的细节都在TaskWorker中,该类实现了Callable接口,因此实现了call()这个方法,该方法中实现了任务规划的细节,下面先来看下该类中包含的方法:
这里写图片描述
该类中包含了三个内部方法,从三个方法的名称可以看到三个方法的作用,首先是scheduleNewTasks(),这个方法完成了一个新job的任务规划,具体如下:
这里写图片描述
该方法,主要是根据一定的策略将该job的tasks划分到不同的groomserver上去,图中划红线的地方完成了具体的规划,该代码主要是,不停的调用jobinprogress对象的obtainNewTask方法,该方法中有一个策略,将task分配到某个groom上去,具体的细节感兴趣可以研究一下,这样所有的task已经与一些groomserver对应起来了,下面的任务就是将任务转换成action,最后用sendDirecticesToGrooms将这些action封装成derective对象发送到对应的groomserver上去,这里虽然是“发送”,其实则不然,在sendDirecticesToGrooms方法中根本没有发送什么消息,而是直接获得对应groomserver的远程代理,然后处理这些规划好的任务,具体的细节感兴趣的可以看一下。
到此为止,一个job从开始用户的提交,都bspmaster的划分、再到真正的规划到groomserver上的过程已经全部完成,以上所有内容纯属本人研究成果,如有不对的地方还望大家指教。

2 0