一、自带的FIFO调度器:
Task分配流程:
1.对于目前的Hadoop任务调度设计来看,分配过程是一个“拉”的过程,即每一个TaskTracker节点主动向JobTracker节点请求作业的任务,而不是当有新作业的时候,JobTracker节点主动给TaskTracker节点分配任务。Cluster运行期,每个TT都要向JT汇报状态信息(默认时间间隔为3秒),这包括TT自身的状态属性、运行在TT上每个task的状态、slot的设置情况等。这些状态信息只是源数据(raw data),提供给JT做分析决策使用,task scheduler也需要它来分配Task。
2.先计算出scheduler依赖的FIFO job queue中有多少task还没有执行,这些将要执行的task越多,当前Cluster的负载就越大。TT的负载与Cluster的负载是差不多相互影响的,如果Cluster的负载很大,那么所有TT就得满负载工作;如果Cluster将要执行的task不多的话,那么相应地TT也可以减少些task 分配。无论怎样,任务调度器JobQueueTaskScheduler总是按照优先级的FIFO来调度每一个Job的Map任务,但对于每一个Job,它只给一次机会,也就是说它顶多只调度该Job的一个Map任务,然后就再调度其它Job的一个Map任务给当前的TaskTracker节点,同时优先分配一个Job的本地任务,当给当前的TaskTracker节点分配了一个非本地任务时,任务调度器JobQueueTaskScheduler就不会再给该TaskTracker节点分配Map任务了,尽管该TaskTracker节点还有空闲的Map Slot。这主要考虑到TaskTracker节点执行非本地任务的代价(CPU不是主要的,关键是网络带宽)。
计算一个TaskTracker节点是否需要保留部分计算能力(Map/Reduce Slots):
在任务调度器JobQueueTaskScheduler的实现中,如果在集群中的TaskTracker节点比较多的情况下,它总是会想办法让若干个TaskTracker节点预留一些空闲的slots(计算能力),以便能够快速的处理优先级比较高的Job的Task或者某个任务对应的推测任务,以保证已经被调度的作业的完成。
Map分配流程图:
转载因子:剩余的任务数量和集群最大能够运行的任务数量的比值。
![](//img.blog.itpub.net/blog/attachment/201507/9/29754888_1436436601gm8Z.gif?x-oss-process=style/bb)
Reduce分配流程图:
![](//img.blog.itpub.net/blog/attachment/201507/9/29754888_1436436653EH9T.gif?x-oss-process=style/bb)
简单记录下 Capacity Scheduler和fair Scheduler:
二、Capacity Scheduler :
调度算法:
1.选择queue队列
-按资源使用率 numSlotsOccupied(槽位占用数) / capacity(容量: % cluster slots) 由小到大排序 。
-跳过已超过max-capacity的queue。(max-capacity(% cluster slots):最大容量)
2.从queue中选择job
-基于优先级(默认关闭)的FIFO排序。 (基于优先级和提交时间排序,如果没有开启优先级则只根据提交时间排序)
-选择一个Job 选中的作业需满足两个条件:
1).作业所属的用户的使用资源没有达到上限
2). 该TaskTracker节点剩余的内存足够来运行该Job的Task
当该TaskTracker的内存不能满足作业的内存需求时,那么调度器会判断该作业是否有待运行的任务并且
保留的TaskTracker是否足够。如果是,则跳过该JobInProgress,取出队列中的下一个JobInProgress。否则
将该tasktracker中的内存solt保留给该Job(保留给该job的名下,这样做是为了使该作业不至于饿死,如果
TaskTracker中可用的solt数量大于等于Job中每个任务所需要的solt的数量,那么TaskTracker会释放掉为该
Job预留的solt,然后从Job中挑选一个任务在TaskTracker上执行)
![](http://img.blog.itpub.net/blog/attachment/201507/10/29754888_1436512647150I.jpg?x-oss-process=style/bb)
3.从job中选择task
-map task会考虑本地。
三、Fair Scheduler :
调度算法:
1.选择Pool:
判断当前运行的任务数目小于最小共享数目。(Fair算法,只考虑内存使用, 后边注释)
如果二个组都小于,则比较最小共享占比。即当前运行的数 / 该组的最小共享数。
如果二个组都大于,则比较权重比。即运行任务数 / 权重系数。(权重越高,被选中的几率越高,且获得资源时获取的量也越大)
如果二者还是相等,则根据起始时间来比较。
2.选择job:
默认采用Fair算法,可支持FIFO、Fair、DRF算法
FIFO:先按照优先级高低调度,如果优先级相同,则按照提交时间先后顺序调度,如果提交时间相同,则按照(队列或者应用程序)名称大小(字符串比较)调度;
FAIR:按照内存资源使用量比率调度,即按照used_memory(使用的内存)/minShare(最少资源保证量,只考虑内存)大小调度(核心思想是按照该调度算法决定调度顺序,但还需考虑一些边界情况);
DRF:借鉴了Mesos中的设计策略,按照主资源公平调度算法进行调度,具体已经在Apache Mesos调度器机制进行了介绍。
最后 借用董专家的一张图说明 Capacity 和 Fair 之间的区别 :
![](http://img.blog.itpub.net/blog/attachment/201507/13/29754888_1436770059ZpPj.jpg?x-oss-process=style/bb)
设置任务执行的队列以及优先级 :
作业提交到的队列:mapreduce.job.queuename
作业优先级:mapreduce.job.priority
Pig版本:
SET mapreduce.job.queuename root.etl.distcp;
SET mapreduce.job.priority HIGH;
Hive版本:
SET mapreduce.job.queuename=root.etl.distcp;
SET mapreduce.job.priority=HIGH;
MapReduce版本:
hadoop jar app.jar -D mapreduce.job.queuename=root.etl.distcp -D mapreduce.job.priority=HIGH
来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/29754888/viewspace-1220318/,如需转载,请注明出处,否则将追究法律责任。
转载于:http://blog.itpub.net/29754888/viewspace-1220318/