Hadoop中Speculative Task调度策略
来源:互联网 发布:约翰霍普金斯大学知乎 编辑:程序博客网 时间:2024/06/07 01:36
转自:http://dongxicheng.org/mapreduce/hadoop-speculative-task/
1. 背景
Speculative Task,又叫推测式任务,是指在分布式集群环境下,因为程序bug,负载不均衡或者资源分布不均,造成同一个job的多个task运行速度不一致,有的task运行速度明显慢于其他task(比如:一个job的某个task进度只有10%,而其他所有task已经运行完毕),则这些task拖慢了作业的整体执行进度,为了避免这种情况发生,Hadoop会为该task启动speculative task,让该speculative task与原始task同时运行,哪个先运行完,则使用它的结果。
Speculative Task思路是以空间换时间的,同时启动多个相同task,哪个完成的早,则采用哪个task的结果,这样明显可以提高任务计算速度,但是,这样却会占用更多的资源,在集群资源紧缺的情况下,合理的控制Speculative Task,可在多用少量资源情况下,减少大作业的计算时间。
本文主要介绍了Hadoop各个版本中Speculative Task设计思路,并指出了各自的不足及改进之处。
2. Hadoop 0.20.2和1.0.0中的算法
【算法流程】
如果一个task满足以下条件,则会为该task启动speculative task:
(1)该task还未启动任何speculative task(TaskInProgress仅对应一个running的task)
(2)在60s内落后(同一个作业所有task的)平均进度20%
某个Task可能对应多个正在运行的attempt task,任何一个运行结束,则会kill(不是fail)其他task。
【相关代码】
boolean
hasSpeculativeTask(
long
currentTime,
double
averageProgress) {
// these constants should be examined
// in more depth eventually...
//
if
(!skipping && activeTasks.size() <= MAX_TASK_EXECS &&
(averageProgress - progress >= SPECULATIVE_GAP) &&
(currentTime - startTime >= SPECULATIVE_LAG)
&& completes ==
0
&& !isOnlyCommitPending()) {
return
true
;
}
return
false
;
}
【存在问题】
以上算法可能造成以下几个问题:
(1) 作业的某个task被卡在87.7%处(MAPREDUCE-94)
(2) 当作业将要运行结束时,总不会启动speculative task
(3) 各个参数不可配置(SPECULATIVE_GAP,SPECULATIVE_LAG),不够灵活。
3. Hadoop 0.21.0中的算法
为了对Hadoop-0.20.2中的算法进行改进,Hadoop-0.21.0进行了以下优化:
(1) 添加了三个可配置选项
mapreduce.job.speculative.slownodethreshold,默认是1,用于判断某个TaskTracker是否适合启动某个task的speculative task
mapreduce.job.speculative.slowtaskthreshold,默认是1,用于判断某个task是否可以启动speculative task
mapreduce.job.speculative.speculativecap, 默认是0.1,用于限定某个job最多同时启动的spculative task的数目
(2) 限定条件
如果一个tasktracker/job/task满足以下条件,则会在该tasktracker上为该task启动一个speculative task:
(1) Job已经启动的specutive task数目小于SpeculativeCap
(2) 该TaskTracker上该Job的所有task平均进度不小于SlowNodeThreshold,具体判断方法为:
tasktracker. mean-job.progessRate >job.std*job. SlowNodeThreshold
其中,tasktracker. Mean为该job在该tasktracker正在运行/已经运行完成的task的平均进度,job.progessRate为该作业的平均计算速度,job.std为该作业所有task计算速度的标准方差。
(3) 按照Task剩余时间,对Task进行排序
Task剩余时间定义为:(1-progress) / progressRate,其中process为task当前进度,progressRate为task的平均计算速度:progressRate= progress/deltaTime,其中deltaTime为该task启动以来所经历的时间
(4) 选择一个剩余时间最多,且 mean-progessRate >std*SlowTaskThreshold的task,并为该task启动speculative task,,其中mean为所有task平均计算速度,std为所有task计算速度的标准方差。
(3) 存在问题
(1)MAPREDUCE-2062
当一个作业只有一个task时,所有task的计算速度的标准方差为0,因而,总会为这样的作业启动speculative task
如果一个作业仅有一个task正在运行,则所有task的标准方差仍未0,Hadoop很可能为其他所有task启动speculative task。
(2)MAPREDUCE-3895
在Hadoop中,reduce task进度(对应上面的progress变量)计算很不合理,采用的方法是,将reduce task分为三个子过程:shuffle(copy),sort和reduce,各个阶段占进度的1/3,比如,一个task的shuffle阶段刚结束,它的进度应该是33.3%。 对于大部分作业,reduce task的进度变化并不是均匀的,一个task在某一时刻进度为33.3%,下一秒进度可能变为66.6%,这主要是因为sort阶段所做工作非常少,时间很短。也正是由于以上原因,reduce task很容易被误判速度过慢,进而启动speculative task。一种可行的解决方案是将sort阶段利用某个数学模型平滑处理。
4. 终极解决方案
拖后腿task出现的原因是系统负载不均衡和资源分配不均。尤其是在异构Hadoop集群中,拖后腿task会经常出现,而且最好不要打开speculative task功能,否则会出现大量的speculative task,造成严重的资源浪费,因为当前所有的speculative task解决方案均是假设集群是同构的。
为什么会造成这种问题?根本原因这种基于speculative task来解决拖后腿task是有问题的。拖后腿task最终应该通过调度器解决:每个TaskTracker通过heartbeat汇报自己机器上的资源分布情况和当前资源使用情况,比如CPU个数,CPU利用率,内存剩余量,IO负载等,然后由调度器根据当前资源使用情况,动态对任务进行调度(参考https://issues.apache.org/jira/browse/MAPREDUCE-1380),进而最大限度避免产生拖后腿task。
关于拖后腿task,还有一个需要解决的问题是,防止为某个task启动speculative task后,该task又变成拖后腿task,比如:某个node上所有task均往一个磁盘上写数据,且该磁盘负载很重,而此时又将一个speculative task调度到该节点上(也往该磁盘上写数据),此时,该speculative task变得缓慢,因而有人提出了Hadoop disk scheduler,具体参考:https://issues.apache.org/jira/browse/MAPREDUCE-2636
5. 关于Speculative Task的Hadoop代码
Hadoop中,关于推测式任务的相关代码均在文件JobInProgress.java和TaskInProgress.java中,JobInProgress.java主要函数定义如下:
protected
synchronized
TaskInProgress findSpeculativeTask(
Collection<TaskInProgress> list, String taskTrackerName,
String taskTrackerHost, TaskType taskType) {….}
TaskInProgress.java中主要函数定义如下:
boolean
canBeSpeculated(
long
currentTime){…}
PS.failed task可理解为自杀,也就是task本身出了问题而自杀;killed task可理解为是他杀,也就是jobtracker认为这个任务的执行是多余的,所以把任务直接杀掉。起初用hadoop的时候经常在一个complete的job中看到几个failed 或者是 killed task,还经常好奇为什么有的时候task的失败不会影响到整个job的失败,而有的时候就会使整个job的失败,到底failed和killed task对整个job的影响是什么?
failed task
failed task出现的原因可分为以下几种情况:
1 child task失败,比如map/reduce任务中抛出了异常,child JVM会将这个error汇报给tasktracker,tasktracker再回将这个error汇报给jobtracker
2 child JVM失败,比如启动child task的JVM本身出现了bug,导致进程直接死掉,此时tasktracker会知道child JVM已经退出,并汇报给jobtracker此次task attempt失败
3 任务超时,如果某个任务很长时间都没有更新状态,则认为任务超时。有的任务虽然执行时间非常长,但它不停的在更新自己的状态,所以系统也不会认为这是个超时任务
4 tasktracker由于软件或硬件的原因直接挂掉了。对于这种情况,tasktracker会停止向jobtracker发送心跳,jobtracker会认为这是个dead node并把该节点加入黑名单,从此不再给这个节点分配任务,直到问题被修复后tasktracker重新汇报心跳。我遇到最囧的情况就是当各节点hosts不一致的时候,会出现tasktracker向jobtasker发送心跳,但jobtracker不能正确向tasktracker,形成了半死不活的节点~。
hadoop本身的一个设计理念就是在普通的pc硬件上构建高可靠性的系统,任何failed task都不会引起整个job的失败,因为所有失败的任务都会被重新执行(reschedule execution),只有当重新执行的次数超过4次,才会把这任务标记为失败,导致整个job的失败。
killed task
在介绍killed task之前,先介绍一下speculative execution。举个简单的例子,如果某个job有2000个map task,已经完成了1999个,只剩下一个task由于硬件比较慢而成为拖尾任务,为了减少拖尾任务对整个job运行时间的影响,jobtracker会重新启动一个一模一样的duplicate task和原有的task并行的执行,这样有一个task执行成功,整个map过程就会结束。speculative execution只有个处理拖尾任务的优化策略,并不能提高系统的可靠性。
介绍完speculative execution后我们来看看killed task的情况。killed task可能在两种情况下发生,一个是speculative execution中两个并行duplicate task中如果有一个执行成功,另一个将被kill掉;第二种情况是如果某个tasktracker挂了,那么正在该节点上面跑的任务都将被标记为killed
- Hadoop中Speculative Task调度策略
- Hadoop中Speculative Task调度策略
- Hadoop中Speculative Task调度策略
- Hadoop中Speculative Task调度策略
- Hadoop中的Speculative Task调度策略
- Hadoop Speculative Task
- Hadoop 推测式任务 Hadoop Speculative Task
- Apache Spark调度之Speculative Task机制详细探究
- Speculative Execution in Hadoop
- Speculative Execution in Hadoop
- HBase MapReduce与Speculative Task
- HBase MapReduce与Speculative Task
- Hadoop使用公平调度策略
- Hadoop Speculative Execution - Hadoop推测执行
- Hadoop yarn任务调度策略介绍
- hadoop资源调度策略方案选择备忘录
- Hadoop yarn任务调度策略介绍
- Hadoop 坑爹的Speculative 机制
- [对内测试Day10.16]贪心+读入+DP+小学数学
- 【转载】Linux SHELL if 命令参数说明
- 【转载】在Linux下限制用户登陆IP
- hive --service hiveserver2
- hwi(hive web interface)-hive web页面的搭建
- Hadoop中Speculative Task调度策略
- 搭建antlr4.2.2开发环境
- 数据结构实验之栈与队列二:一般算术表达式转换成后缀式
- JAVA如何避免死锁的几个常见方法
- awk输出单引号
- 很牛的人的日志
- 单例实现的七种方式
- 使用hive自定义函数pom.xml的写法
- AM2 开发日志1 10.16