Job的map任务分配

来源:互联网 发布:tgp网络出口不稳定 编辑:程序博客网 时间:2024/05/21 19:30

在前面的博文中,我介绍了Job的调度以及Job的任务分解,但对于Job的调度我只是从宏观的角度作了详细的说明,而关于JobInProgress具体是如何给TaskTracker分配本地Map Task和非本地MapTask的,将是本文将要讲解的重点。

      先来看看JobInProgress是如何定义本地Map Task的。在前面的博文:Job的任务分解中,我自己给出了一个关于“预分配map任务”的解释,在这个过程当中,待分配的map任务被放到了JobInProgress的两个集合中:

Map<Node, List<TaskInProgress>> nonRunningMapCache;

List<TaskInProgress> nonLocalMaps;

而正在被TaskTracker的运行的map任务被存放在:

Map<Node, List<TaskInProgress>> RunningMapCache;

List<TaskInProgress> nonLocalRunningMaps;

显然地,本地map任务都来自于nonRunningMapCache集合,非本地map任务优先来自nonRunningMapCache,其次来自nonLocalMaps,最后也会从已经被执行的任务RunningMapCachenonLocalRunningMaps中选取。下面就来看看JobInProgress是如何给TaskTracker分配本地map任务的吧!



在给TaskTracker分配一个本地map任务的过程中需要说明的有如下几点:

1.如何判断是否应该给当前TaskTracker分配一个map任务。

   JobInProgress会记录每一执行它的任务的TaskTracker的信息,这个信息包括TaskTracker执行这个Job的tasks失败的次数。当这个次数超过一个阈值的时候,就任务不应该再给TaskTracker这个分配自己的tasks了,应该它执行自己的tasks的失败率太高。当然,这个阈值可以通过Job的配置文件来设置,对应的项是:mapred.max.tracker.failures。

2.如何检查TaskTracker当前的资源是否能够运行一个map任务

    TaskTracker每次向JobTracker发送heartheat心跳包的时候会带上自己当前的资源信息(包括正在使用的,空闲的),返回时就会捎带JobTracker分配的tasks。比较TaskTracker的资源剩余量和一个任务的估计使用量就可以知道一个TaskTracker能够运行一个task。值得说明的是,这种判断不一定准确,一是因为TaskTracker的资源剩余量是动态变化的,当前获取的TaskTracker资源使用情况并不一定是最新的;而是因为并不能准确的估算出一个task到底需要多少资源。(这里提到的资源主要是指内存)

3.如何从集合cacheForLevel中选取一个map任务

     1).从cacheForLevel中依次选取一个map任务;

     2).如果这个map任务可执行并且没有正在被执行,到3);否则到6);

     3).如果这个TaskTracker以前执行该map任务没有失败过或者集群中所有的主机执行该map任务都失败过,到4);否则到5);

     4).从cacheForLevel中删除该map任务,并把该map任务分配给这个TaskTracker;到8);

     5).如果该map任务对应的数据在TaskTracker上,则到6);否则到7);

     6).从cacheForLevel中删除该map任务;

     7).回到1);

     8).结束。


      再来看看JobInProgress是如何给TaskTracker分配非本地map任务的,虽然这个过程比较的繁琐,但是并不复杂。


      关于从RunningMapCachenonLocalRunningMaps中选取一个本地或者非本地的正在被执行的map任务的方法基本上类似于从nonRunningMapCachenonLocalMaps中选取一个本地或者非本地的map任务的方法。不同的就是如何判断一个正在运行的task是speculative的。这个主要从这个正在执行的task的执行进度来衡量,说白了就是看看当前的Job中又没有拖后退的task。在实际的应用当中,总是会出现这样有趣的一个现象,那就是一个作业中总是有那么几个执行很慢的tasks,所以为了保证作业的整体执行进度,我们往往会把这些拖后退的tasks交给另外的TaskTrackers来执行,而这些拖后退的tasks在这些新的上执行很快TaskTrackers。从大的方面来讲,出现这种情况的原因很可能与操作系统的进程调度策略有关。

      哦,对了,在向JobTracker提交作业Job的时候,客户端可以自己设置作业Job在执行的时候是否需要考虑处理这种拖后腿的task,即可以通过作业的配置文件中的mapred.map.tasks.speculative.execution项来设置(false/true),同时这个值默认是true