Speculative Task称为推测式任务,是Map/Reduce框架中的重要优化算法,是为了解决某些运行速度较慢的task,影响整个job的执行进度的问题。在分布式集群环境下,因为程序bug、负载不均衡、资源分布不均、slave node处理能力不同,会出现同一个job的多个task运行速度不一致,有的task运行速度明显慢于其他task的情况,这些task的出现会影响整个job的整体运行速度。Speculative task技术会针对那些慢于平均进度的Task启动Speculative Task,此时如果原Task在Speculative Task前完成,则Speculative Task会被终止,同样的,如果Speculative Task先于原Task完成则原来的Task会被终止。
在Hadoop平台下,我们会发现启用了speculative execution选项后,会为每一个task启用多个相同的attempt tasks(执行这些tasks的slave节点不同),当任意一个attempt task执行完成后,将kill掉所有其他相同的attempt tasks,从而提高每个task的平均执行效率。不同Hadoop版本下speculative task调度算法的实现可以参考http://dongxicheng.org/mapreduce/hadoop-speculative-task/。
然而,这些attempt tasks同样占用slave节点的资源,当节点资源有限的情况下,会因为这些attempt tasks的出现造成大量的资源浪费,以致频繁出现out of memory/java heap space error的问题(由于我们使用的平台资源有限,在实验过程中这种问题频繁出现)。通过关闭speculative execution选项,可以解决这个问题,具体来说有两种做法(hadoop默认是开启speculative execution选项):
1)在mapred-site.xml中设置:
- <property>
- <name>mapred.map.tasks.speculative.execution</name>
- <value>false</value>
- </property>
- <property>
- <name>mapred.reduce.tasks.speculative.execution</name>
- <value>false</value>
- </property>
2)在提交job,配置job configuration时设置
- conf.setBoolean("mapred.map.tasks.speculative.execution", false);
- conf.setBoolean("mapred.reduce.tasks.speculative.execution", false);
前一种方法是通过修改hadoop配置文件,将对所有job均不执行speculative execution;后一种方法仅对当前设置的job不执行speculative execution,相比较来说,后一种方法更具有灵活性。
我们目前使用的是Hadoop1.0.0版本,使用了后一种配置方法,运行后,每一个task只有一个attempt task在执行,并且,由于减少了slave节点计算资源的浪费,每个task的执行速度有所提升。但缺点是,当一个task在执行过程中出现failed(无论当前执行进度如何),只能重新开启一个同样的task执行,这也在一定程度上造成了速度的下降。所以,是否开启speculative execution选项也是一个权衡的过程。
另外,在查找资料的过程中还发现,有人反映当使用前面第一种方法开启speculative execution选项后,将无法使用第二种方法动态关闭speculative excution;如果使用第一种方法关闭speculative execution选项后,则可以使用第二种方法开启speculative execution选项(https://issues.apache.org/jira/browse/MAPREDUCE-3404)。这似乎是hadoop的版本问题,因为我们在1.0.0下的实验过程中并没有发现这个问题。
转载于:https://blog.51cto.com/drmaxwell/1006159