在现实情况中,用户代码错误不断,进程奔溃,机器故障等等。使用hadoop的好处之一就是可以它能处理这类故障并成功完成任务。需要考虑的实体失败任务为:任务(job),Application Master,NodeManager和ResourceManager。
任务失败
可能存在以下情况:
- MapTask或者ReduceTask中由于代码原因抛出异常,jvm在关闭之前,会通知mrAppMaster这个task任务失败,在mrAppMaster中,错误报告被写入到用户日志并且任务标记为失败,并释放jvm资源,供其他任务使用。对于streaming任务,如果streaming进程以非0退出代码退出,则被标记为失败。这种行为由stream.non.zero.is.failure属性(默认值为true)控制
- jvm突然退出,可能是由于jvm缺陷而导致mr用户代码由于某种特殊原因造成jvm退出。nodeManage会将这消息通知到mrAppMaster,标记此次任务失败
- 任务挂起(可能是由于资源不足造成):一旦mrAppMaster一段时间没有接收到进度的更新,则将任务标记为失败,nodeManager会将该jvm进程杀死。任务失败时长可以由mapreduce.task.timeout来设置。如果为0 ,则表示关闭。如果关闭这个属性,那么可能会造成长时间运行的任务不会被标记为失败,被挂起的任务就会一直不被释放资源,长时间会造成集群效率降低,因此尽量避免这个设置。同时充分保证每个任务定期更新进度。
处理:当mrAppMaster被告知,一个任务失败的时候,会重新调度该任务。mrAppMaster会尝试避免在以前失败过的nodeManager重新调度该任务。此外,一个任务失败的次数超过4次,将不会再重新调度。这个数值由mapreduce.map.maxattempts控制。如果一个任务失败次数大于该属性设置的,则整个作业都会失败。对于一些应用程序中,不希望少部分任务失败,而导致整个作业失败,因为即使一些任务失败,作业的输出结果也是可用的,我们可用通过运行任务失败的最大比例:m