MAPREDUCE-4252. MR2 job never completes with 1 pending task (Tom White via bobby)
git-svn-id: https://svn.apache.org/repos/asf/hadoop/common/trunk@1359747 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
e0f96aa249
commit
6804ef32fc
|
@ -667,6 +667,9 @@ Release 0.23.3 - UNRELEASED
|
||||||
MAPREDUCE-4300. OOM in AM can turn it into a zombie. (Robert Evans via
|
MAPREDUCE-4300. OOM in AM can turn it into a zombie. (Robert Evans via
|
||||||
tgraves)
|
tgraves)
|
||||||
|
|
||||||
|
MAPREDUCE-4252. MR2 job never completes with 1 pending task (Tom White via
|
||||||
|
bobby)
|
||||||
|
|
||||||
Release 0.23.2 - UNRELEASED
|
Release 0.23.2 - UNRELEASED
|
||||||
|
|
||||||
INCOMPATIBLE CHANGES
|
INCOMPATIBLE CHANGES
|
||||||
|
|
|
@ -189,7 +189,7 @@ public abstract class TaskImpl implements Task, EventHandler<TaskEvent> {
|
||||||
|
|
||||||
// Transitions from SUCCEEDED state
|
// Transitions from SUCCEEDED state
|
||||||
.addTransition(TaskState.SUCCEEDED, //only possible for map tasks
|
.addTransition(TaskState.SUCCEEDED, //only possible for map tasks
|
||||||
EnumSet.of(TaskState.SCHEDULED, TaskState.FAILED),
|
EnumSet.of(TaskState.SCHEDULED, TaskState.SUCCEEDED, TaskState.FAILED),
|
||||||
TaskEventType.T_ATTEMPT_FAILED, new MapRetroactiveFailureTransition())
|
TaskEventType.T_ATTEMPT_FAILED, new MapRetroactiveFailureTransition())
|
||||||
.addTransition(TaskState.SUCCEEDED, //only possible for map tasks
|
.addTransition(TaskState.SUCCEEDED, //only possible for map tasks
|
||||||
EnumSet.of(TaskState.SCHEDULED, TaskState.SUCCEEDED),
|
EnumSet.of(TaskState.SCHEDULED, TaskState.SUCCEEDED),
|
||||||
|
@ -618,7 +618,7 @@ public abstract class TaskImpl implements Task, EventHandler<TaskEvent> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void internalError(TaskEventType type) {
|
protected void internalError(TaskEventType type) {
|
||||||
LOG.error("Invalid event " + type + " on Task " + this.taskId);
|
LOG.error("Invalid event " + type + " on Task " + this.taskId);
|
||||||
eventHandler.handle(new JobDiagnosticsUpdateEvent(
|
eventHandler.handle(new JobDiagnosticsUpdateEvent(
|
||||||
this.taskId.getJobId(), "Invalid event " + type +
|
this.taskId.getJobId(), "Invalid event " + type +
|
||||||
|
@ -896,6 +896,16 @@ public abstract class TaskImpl implements Task, EventHandler<TaskEvent> {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TaskState transition(TaskImpl task, TaskEvent event) {
|
public TaskState transition(TaskImpl task, TaskEvent event) {
|
||||||
|
if (event instanceof TaskTAttemptEvent) {
|
||||||
|
TaskTAttemptEvent castEvent = (TaskTAttemptEvent) event;
|
||||||
|
if (task.getState() == TaskState.SUCCEEDED &&
|
||||||
|
!castEvent.getTaskAttemptID().equals(task.successfulAttempt)) {
|
||||||
|
// don't allow a different task attempt to override a previous
|
||||||
|
// succeeded state
|
||||||
|
return TaskState.SUCCEEDED;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//verify that this occurs only for map task
|
//verify that this occurs only for map task
|
||||||
//TODO: consider moving it to MapTaskImpl
|
//TODO: consider moving it to MapTaskImpl
|
||||||
if (!TaskType.MAP.equals(task.getType())) {
|
if (!TaskType.MAP.equals(task.getType())) {
|
||||||
|
|
|
@ -20,6 +20,7 @@ package org.apache.hadoop.mapreduce.v2.app.job.impl;
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
import static org.junit.Assert.assertFalse;
|
import static org.junit.Assert.assertFalse;
|
||||||
import static org.junit.Assert.assertTrue;
|
import static org.junit.Assert.assertTrue;
|
||||||
|
import static org.junit.Assert.fail;
|
||||||
import static org.mockito.Mockito.mock;
|
import static org.mockito.Mockito.mock;
|
||||||
import static org.mockito.Mockito.when;
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
|
@ -129,6 +130,11 @@ public class TestTaskImpl {
|
||||||
return 100;
|
return 100;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void internalError(TaskEventType type) {
|
||||||
|
super.internalError(type);
|
||||||
|
fail("Internal error: " + type);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private class MockTaskAttemptImpl extends TaskAttemptImpl {
|
private class MockTaskAttemptImpl extends TaskAttemptImpl {
|
||||||
|
@ -463,4 +469,31 @@ public class TestTaskImpl {
|
||||||
assertTaskSucceededState();
|
assertTaskSucceededState();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSpeculativeTaskAttemptSucceedsEvenIfFirstFails() {
|
||||||
|
TaskId taskId = getNewTaskID();
|
||||||
|
scheduleTaskAttempt(taskId);
|
||||||
|
launchTaskAttempt(getLastAttempt().getAttemptId());
|
||||||
|
updateLastAttemptState(TaskAttemptState.RUNNING);
|
||||||
|
|
||||||
|
// Add a speculative task attempt that succeeds
|
||||||
|
mockTask.handle(new TaskTAttemptEvent(getLastAttempt().getAttemptId(),
|
||||||
|
TaskEventType.T_ADD_SPEC_ATTEMPT));
|
||||||
|
launchTaskAttempt(getLastAttempt().getAttemptId());
|
||||||
|
commitTaskAttempt(getLastAttempt().getAttemptId());
|
||||||
|
mockTask.handle(new TaskTAttemptEvent(getLastAttempt().getAttemptId(),
|
||||||
|
TaskEventType.T_ATTEMPT_SUCCEEDED));
|
||||||
|
|
||||||
|
// The task should now have succeeded
|
||||||
|
assertTaskSucceededState();
|
||||||
|
|
||||||
|
// Now fail the first task attempt, after the second has succeeded
|
||||||
|
mockTask.handle(new TaskTAttemptEvent(taskAttempts.get(0).getAttemptId(),
|
||||||
|
TaskEventType.T_ATTEMPT_FAILED));
|
||||||
|
|
||||||
|
// The task should still be in the succeeded state
|
||||||
|
assertTaskSucceededState();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue