|
@@ -16,15 +16,15 @@
|
|
* limitations under the License.
|
|
* limitations under the License.
|
|
*/
|
|
*/
|
|
|
|
|
|
-package org.apache.hadoop.yarn.server.nodemanager.containermanager.queuing;
|
|
|
|
|
|
+package org.apache.hadoop.yarn.server.nodemanager.containermanager.scheduler;
|
|
|
|
|
|
import java.io.IOException;
|
|
import java.io.IOException;
|
|
import java.util.ArrayList;
|
|
import java.util.ArrayList;
|
|
import java.util.Arrays;
|
|
import java.util.Arrays;
|
|
|
|
+import java.util.HashMap;
|
|
import java.util.List;
|
|
import java.util.List;
|
|
|
|
|
|
import org.apache.commons.logging.LogFactory;
|
|
import org.apache.commons.logging.LogFactory;
|
|
-import org.apache.hadoop.fs.Path;
|
|
|
|
import org.apache.hadoop.fs.UnsupportedFileSystemException;
|
|
import org.apache.hadoop.fs.UnsupportedFileSystemException;
|
|
import org.apache.hadoop.security.UserGroupInformation;
|
|
import org.apache.hadoop.security.UserGroupInformation;
|
|
import org.apache.hadoop.yarn.api.protocolrecords.GetContainerStatusesRequest;
|
|
import org.apache.hadoop.yarn.api.protocolrecords.GetContainerStatusesRequest;
|
|
@@ -40,35 +40,41 @@ import org.apache.hadoop.yarn.api.records.ExecutionType;
|
|
import org.apache.hadoop.yarn.conf.YarnConfiguration;
|
|
import org.apache.hadoop.yarn.conf.YarnConfiguration;
|
|
import org.apache.hadoop.yarn.exceptions.YarnException;
|
|
import org.apache.hadoop.yarn.exceptions.YarnException;
|
|
import org.apache.hadoop.yarn.security.NMTokenIdentifier;
|
|
import org.apache.hadoop.yarn.security.NMTokenIdentifier;
|
|
|
|
+import org.apache.hadoop.yarn.server.api.records.ContainerQueuingLimit;
|
|
import org.apache.hadoop.yarn.server.nodemanager.ContainerExecutor;
|
|
import org.apache.hadoop.yarn.server.nodemanager.ContainerExecutor;
|
|
|
|
+import org.apache.hadoop.yarn.server.nodemanager.DefaultContainerExecutor;
|
|
import org.apache.hadoop.yarn.server.nodemanager.DeletionService;
|
|
import org.apache.hadoop.yarn.server.nodemanager.DeletionService;
|
|
import org.apache.hadoop.yarn.server.nodemanager.containermanager.BaseContainerManagerTest;
|
|
import org.apache.hadoop.yarn.server.nodemanager.containermanager.BaseContainerManagerTest;
|
|
import org.apache.hadoop.yarn.server.nodemanager.containermanager.ContainerManagerImpl;
|
|
import org.apache.hadoop.yarn.server.nodemanager.containermanager.ContainerManagerImpl;
|
|
import org.apache.hadoop.yarn.server.nodemanager.containermanager.container.ContainerState;
|
|
import org.apache.hadoop.yarn.server.nodemanager.containermanager.container.ContainerState;
|
|
import org.apache.hadoop.yarn.server.nodemanager.containermanager.monitor.ContainersMonitor;
|
|
import org.apache.hadoop.yarn.server.nodemanager.containermanager.monitor.ContainersMonitor;
|
|
import org.apache.hadoop.yarn.server.nodemanager.containermanager.monitor.ContainersMonitorImpl;
|
|
import org.apache.hadoop.yarn.server.nodemanager.containermanager.monitor.ContainersMonitorImpl;
|
|
|
|
+import org.apache.hadoop.yarn.server.nodemanager.executor.ContainerStartContext;
|
|
import org.apache.hadoop.yarn.server.utils.BuilderUtils;
|
|
import org.apache.hadoop.yarn.server.utils.BuilderUtils;
|
|
import org.junit.Assert;
|
|
import org.junit.Assert;
|
|
import org.junit.Test;
|
|
import org.junit.Test;
|
|
|
|
|
|
|
|
+import static org.mockito.Mockito.spy;
|
|
|
|
+
|
|
/**
|
|
/**
|
|
- * Class for testing the {@link QueuingContainerManagerImpl}.
|
|
|
|
|
|
+ * Tests to verify that the {@link ContainerScheduler} is able to queue and
|
|
|
|
+ * make room for containers.
|
|
*/
|
|
*/
|
|
-public class TestQueuingContainerManager extends BaseContainerManagerTest {
|
|
|
|
- public TestQueuingContainerManager() throws UnsupportedFileSystemException {
|
|
|
|
|
|
+public class TestContainerSchedulerQueuing extends BaseContainerManagerTest {
|
|
|
|
+ public TestContainerSchedulerQueuing() throws UnsupportedFileSystemException {
|
|
super();
|
|
super();
|
|
}
|
|
}
|
|
|
|
|
|
static {
|
|
static {
|
|
- LOG = LogFactory.getLog(TestQueuingContainerManager.class);
|
|
|
|
|
|
+ LOG = LogFactory.getLog(TestContainerSchedulerQueuing.class);
|
|
}
|
|
}
|
|
|
|
|
|
- boolean shouldDeleteWait = false;
|
|
|
|
|
|
+ private boolean delayContainers = true;
|
|
|
|
|
|
@Override
|
|
@Override
|
|
protected ContainerManagerImpl createContainerManager(
|
|
protected ContainerManagerImpl createContainerManager(
|
|
DeletionService delSrvc) {
|
|
DeletionService delSrvc) {
|
|
- return new QueuingContainerManagerImpl(context, exec, delSrvc,
|
|
|
|
|
|
+ return new ContainerManagerImpl(context, exec, delSrvc,
|
|
nodeStatusUpdater, metrics, dirsHandler) {
|
|
nodeStatusUpdater, metrics, dirsHandler) {
|
|
@Override
|
|
@Override
|
|
public void
|
|
public void
|
|
@@ -117,33 +123,29 @@ public class TestQueuingContainerManager extends BaseContainerManagerTest {
|
|
}
|
|
}
|
|
|
|
|
|
@Override
|
|
@Override
|
|
- protected DeletionService createDeletionService() {
|
|
|
|
- return new DeletionService(exec) {
|
|
|
|
|
|
+ protected ContainerExecutor createContainerExecutor() {
|
|
|
|
+ DefaultContainerExecutor exec = new DefaultContainerExecutor() {
|
|
@Override
|
|
@Override
|
|
- public void delete(String user, Path subDir, Path... baseDirs) {
|
|
|
|
- // Don't do any deletions.
|
|
|
|
- if (shouldDeleteWait) {
|
|
|
|
|
|
+ public int launchContainer(ContainerStartContext ctx) throws IOException {
|
|
|
|
+ if (delayContainers) {
|
|
try {
|
|
try {
|
|
Thread.sleep(10000);
|
|
Thread.sleep(10000);
|
|
- LOG.info("\n\nSleeping Pseudo delete : user - " + user + ", " +
|
|
|
|
- "subDir - " + subDir + ", " +
|
|
|
|
- "baseDirs - " + Arrays.asList(baseDirs));
|
|
|
|
} catch (InterruptedException e) {
|
|
} catch (InterruptedException e) {
|
|
- e.printStackTrace();
|
|
|
|
|
|
+ // Nothing..
|
|
}
|
|
}
|
|
- } else {
|
|
|
|
- LOG.info("\n\nPseudo delete : user - " + user + ", " +
|
|
|
|
- "subDir - " + subDir + ", " +
|
|
|
|
- "baseDirs - " + Arrays.asList(baseDirs));
|
|
|
|
}
|
|
}
|
|
|
|
+ return super.launchContainer(ctx);
|
|
}
|
|
}
|
|
};
|
|
};
|
|
|
|
+ exec.setConf(conf);
|
|
|
|
+ return spy(exec);
|
|
}
|
|
}
|
|
|
|
|
|
@Override
|
|
@Override
|
|
public void setup() throws IOException {
|
|
public void setup() throws IOException {
|
|
|
|
+ conf.setInt(
|
|
|
|
+ YarnConfiguration.NM_OPPORTUNISTIC_CONTAINERS_MAX_QUEUE_LENGTH, 10);
|
|
super.setup();
|
|
super.setup();
|
|
- shouldDeleteWait = false;
|
|
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
/**
|
|
@@ -152,7 +154,6 @@ public class TestQueuingContainerManager extends BaseContainerManagerTest {
|
|
*/
|
|
*/
|
|
@Test
|
|
@Test
|
|
public void testStartMultipleContainers() throws Exception {
|
|
public void testStartMultipleContainers() throws Exception {
|
|
- shouldDeleteWait = true;
|
|
|
|
containerManager.start();
|
|
containerManager.start();
|
|
|
|
|
|
ContainerLaunchContext containerLaunchContext =
|
|
ContainerLaunchContext containerLaunchContext =
|
|
@@ -209,7 +210,6 @@ public class TestQueuingContainerManager extends BaseContainerManagerTest {
|
|
*/
|
|
*/
|
|
@Test
|
|
@Test
|
|
public void testQueueMultipleContainers() throws Exception {
|
|
public void testQueueMultipleContainers() throws Exception {
|
|
- shouldDeleteWait = true;
|
|
|
|
containerManager.start();
|
|
containerManager.start();
|
|
|
|
|
|
ContainerLaunchContext containerLaunchContext =
|
|
ContainerLaunchContext containerLaunchContext =
|
|
@@ -248,17 +248,18 @@ public class TestQueuingContainerManager extends BaseContainerManagerTest {
|
|
.getContainerStatuses(statRequest).getContainerStatuses();
|
|
.getContainerStatuses(statRequest).getContainerStatuses();
|
|
for (ContainerStatus status : containerStatuses) {
|
|
for (ContainerStatus status : containerStatuses) {
|
|
Assert.assertEquals(
|
|
Assert.assertEquals(
|
|
- org.apache.hadoop.yarn.api.records.ContainerState.QUEUED,
|
|
|
|
|
|
+ org.apache.hadoop.yarn.api.records.ContainerState.SCHEDULED,
|
|
status.getState());
|
|
status.getState());
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ ContainerScheduler containerScheduler =
|
|
|
|
+ containerManager.getContainerScheduler();
|
|
// Ensure both containers are properly queued.
|
|
// Ensure both containers are properly queued.
|
|
- Assert.assertEquals(2, containerManager.getContext().getQueuingContext()
|
|
|
|
- .getQueuedContainers().size());
|
|
|
|
- Assert.assertEquals(1, ((QueuingContainerManagerImpl) containerManager)
|
|
|
|
- .getNumQueuedGuaranteedContainers());
|
|
|
|
- Assert.assertEquals(1, ((QueuingContainerManagerImpl) containerManager)
|
|
|
|
- .getNumQueuedOpportunisticContainers());
|
|
|
|
|
|
+ Assert.assertEquals(2, containerScheduler.getNumQueuedContainers());
|
|
|
|
+ Assert.assertEquals(1,
|
|
|
|
+ containerScheduler.getNumQueuedGuaranteedContainers());
|
|
|
|
+ Assert.assertEquals(1,
|
|
|
|
+ containerScheduler.getNumQueuedOpportunisticContainers());
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
/**
|
|
@@ -268,7 +269,6 @@ public class TestQueuingContainerManager extends BaseContainerManagerTest {
|
|
*/
|
|
*/
|
|
@Test
|
|
@Test
|
|
public void testStartAndQueueMultipleContainers() throws Exception {
|
|
public void testStartAndQueueMultipleContainers() throws Exception {
|
|
- shouldDeleteWait = true;
|
|
|
|
containerManager.start();
|
|
containerManager.start();
|
|
|
|
|
|
ContainerLaunchContext containerLaunchContext =
|
|
ContainerLaunchContext containerLaunchContext =
|
|
@@ -319,18 +319,19 @@ public class TestQueuingContainerManager extends BaseContainerManagerTest {
|
|
status.getState());
|
|
status.getState());
|
|
} else {
|
|
} else {
|
|
Assert.assertEquals(
|
|
Assert.assertEquals(
|
|
- org.apache.hadoop.yarn.api.records.ContainerState.QUEUED,
|
|
|
|
|
|
+ org.apache.hadoop.yarn.api.records.ContainerState.SCHEDULED,
|
|
status.getState());
|
|
status.getState());
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ ContainerScheduler containerScheduler =
|
|
|
|
+ containerManager.getContainerScheduler();
|
|
// Ensure two containers are properly queued.
|
|
// Ensure two containers are properly queued.
|
|
- Assert.assertEquals(2, containerManager.getContext().getQueuingContext()
|
|
|
|
- .getQueuedContainers().size());
|
|
|
|
- Assert.assertEquals(0, ((QueuingContainerManagerImpl) containerManager)
|
|
|
|
- .getNumQueuedGuaranteedContainers());
|
|
|
|
- Assert.assertEquals(2, ((QueuingContainerManagerImpl) containerManager)
|
|
|
|
- .getNumQueuedOpportunisticContainers());
|
|
|
|
|
|
+ Assert.assertEquals(2, containerScheduler.getNumQueuedContainers());
|
|
|
|
+ Assert.assertEquals(0,
|
|
|
|
+ containerScheduler.getNumQueuedGuaranteedContainers());
|
|
|
|
+ Assert.assertEquals(2,
|
|
|
|
+ containerScheduler.getNumQueuedOpportunisticContainers());
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
/**
|
|
@@ -344,7 +345,6 @@ public class TestQueuingContainerManager extends BaseContainerManagerTest {
|
|
*/
|
|
*/
|
|
@Test
|
|
@Test
|
|
public void testKillOpportunisticForGuaranteedContainer() throws Exception {
|
|
public void testKillOpportunisticForGuaranteedContainer() throws Exception {
|
|
- shouldDeleteWait = true;
|
|
|
|
containerManager.start();
|
|
containerManager.start();
|
|
|
|
|
|
ContainerLaunchContext containerLaunchContext =
|
|
ContainerLaunchContext containerLaunchContext =
|
|
@@ -393,11 +393,11 @@ public class TestQueuingContainerManager extends BaseContainerManagerTest {
|
|
.getContainerStatuses(statRequest).getContainerStatuses();
|
|
.getContainerStatuses(statRequest).getContainerStatuses();
|
|
for (ContainerStatus status : containerStatuses) {
|
|
for (ContainerStatus status : containerStatuses) {
|
|
if (status.getContainerId().equals(createContainerId(0))) {
|
|
if (status.getContainerId().equals(createContainerId(0))) {
|
|
- Assert.assertTrue(status.getDiagnostics()
|
|
|
|
- .contains("Container killed by the ApplicationMaster"));
|
|
|
|
|
|
+ Assert.assertTrue(status.getDiagnostics().contains(
|
|
|
|
+ "Container Killed to make room for Guaranteed Container"));
|
|
} else if (status.getContainerId().equals(createContainerId(1))) {
|
|
} else if (status.getContainerId().equals(createContainerId(1))) {
|
|
Assert.assertEquals(
|
|
Assert.assertEquals(
|
|
- org.apache.hadoop.yarn.api.records.ContainerState.QUEUED,
|
|
|
|
|
|
+ org.apache.hadoop.yarn.api.records.ContainerState.SCHEDULED,
|
|
status.getState());
|
|
status.getState());
|
|
} else if (status.getContainerId().equals(createContainerId(2))) {
|
|
} else if (status.getContainerId().equals(createContainerId(2))) {
|
|
Assert.assertEquals(
|
|
Assert.assertEquals(
|
|
@@ -420,6 +420,197 @@ public class TestQueuingContainerManager extends BaseContainerManagerTest {
|
|
contStatus1.getState());
|
|
contStatus1.getState());
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ /**
|
|
|
|
+ * 1. Submit a long running GUARANTEED container to hog all NM resources.
|
|
|
|
+ * 2. Submit 6 OPPORTUNISTIC containers, all of which will be queued.
|
|
|
|
+ * 3. Update the Queue Limit to 2.
|
|
|
|
+ * 4. Ensure only 2 containers remain in the Queue, and 4 are de-Queued.
|
|
|
|
+ * @throws Exception
|
|
|
|
+ */
|
|
|
|
+ @Test
|
|
|
|
+ public void testQueueShedding() throws Exception {
|
|
|
|
+ containerManager.start();
|
|
|
|
+
|
|
|
|
+ ContainerLaunchContext containerLaunchContext =
|
|
|
|
+ recordFactory.newRecordInstance(ContainerLaunchContext.class);
|
|
|
|
+ containerLaunchContext.setCommands(Arrays.asList("sleep 100"));
|
|
|
|
+
|
|
|
|
+ List<StartContainerRequest> list = new ArrayList<>();
|
|
|
|
+ list.add(StartContainerRequest.newInstance(
|
|
|
|
+ containerLaunchContext,
|
|
|
|
+ createContainerToken(createContainerId(0), DUMMY_RM_IDENTIFIER,
|
|
|
|
+ context.getNodeId(),
|
|
|
|
+ user, BuilderUtils.newResource(2048, 1),
|
|
|
|
+ context.getContainerTokenSecretManager(), null,
|
|
|
|
+ ExecutionType.GUARANTEED)));
|
|
|
|
+
|
|
|
|
+ StartContainersRequest allRequests =
|
|
|
|
+ StartContainersRequest.newInstance(list);
|
|
|
|
+ containerManager.startContainers(allRequests);
|
|
|
|
+
|
|
|
|
+ list = new ArrayList<>();
|
|
|
|
+ list.add(StartContainerRequest.newInstance(
|
|
|
|
+ containerLaunchContext,
|
|
|
|
+ createContainerToken(createContainerId(1), DUMMY_RM_IDENTIFIER,
|
|
|
|
+ context.getNodeId(),
|
|
|
|
+ user, BuilderUtils.newResource(512, 1),
|
|
|
|
+ context.getContainerTokenSecretManager(), null,
|
|
|
|
+ ExecutionType.OPPORTUNISTIC)));
|
|
|
|
+ list.add(StartContainerRequest.newInstance(
|
|
|
|
+ containerLaunchContext,
|
|
|
|
+ createContainerToken(createContainerId(2), DUMMY_RM_IDENTIFIER,
|
|
|
|
+ context.getNodeId(),
|
|
|
|
+ user, BuilderUtils.newResource(512, 1),
|
|
|
|
+ context.getContainerTokenSecretManager(), null,
|
|
|
|
+ ExecutionType.OPPORTUNISTIC)));
|
|
|
|
+ list.add(StartContainerRequest.newInstance(
|
|
|
|
+ containerLaunchContext,
|
|
|
|
+ createContainerToken(createContainerId(3), DUMMY_RM_IDENTIFIER,
|
|
|
|
+ context.getNodeId(),
|
|
|
|
+ user, BuilderUtils.newResource(512, 1),
|
|
|
|
+ context.getContainerTokenSecretManager(), null,
|
|
|
|
+ ExecutionType.OPPORTUNISTIC)));
|
|
|
|
+ list.add(StartContainerRequest.newInstance(
|
|
|
|
+ containerLaunchContext,
|
|
|
|
+ createContainerToken(createContainerId(4), DUMMY_RM_IDENTIFIER,
|
|
|
|
+ context.getNodeId(),
|
|
|
|
+ user, BuilderUtils.newResource(512, 1),
|
|
|
|
+ context.getContainerTokenSecretManager(), null,
|
|
|
|
+ ExecutionType.OPPORTUNISTIC)));
|
|
|
|
+ list.add(StartContainerRequest.newInstance(
|
|
|
|
+ containerLaunchContext,
|
|
|
|
+ createContainerToken(createContainerId(5), DUMMY_RM_IDENTIFIER,
|
|
|
|
+ context.getNodeId(),
|
|
|
|
+ user, BuilderUtils.newResource(512, 1),
|
|
|
|
+ context.getContainerTokenSecretManager(), null,
|
|
|
|
+ ExecutionType.OPPORTUNISTIC)));
|
|
|
|
+ list.add(StartContainerRequest.newInstance(
|
|
|
|
+ containerLaunchContext,
|
|
|
|
+ createContainerToken(createContainerId(6), DUMMY_RM_IDENTIFIER,
|
|
|
|
+ context.getNodeId(),
|
|
|
|
+ user, BuilderUtils.newResource(512, 1),
|
|
|
|
+ context.getContainerTokenSecretManager(), null,
|
|
|
|
+ ExecutionType.OPPORTUNISTIC)));
|
|
|
|
+
|
|
|
|
+ allRequests = StartContainersRequest.newInstance(list);
|
|
|
|
+ containerManager.startContainers(allRequests);
|
|
|
|
+
|
|
|
|
+ ContainerScheduler containerScheduler =
|
|
|
|
+ containerManager.getContainerScheduler();
|
|
|
|
+ // Ensure all containers are properly queued.
|
|
|
|
+ int numTries = 30;
|
|
|
|
+ while ((containerScheduler.getNumQueuedContainers() < 6) &&
|
|
|
|
+ (numTries-- > 0)) {
|
|
|
|
+ Thread.sleep(100);
|
|
|
|
+ }
|
|
|
|
+ Assert.assertEquals(6, containerScheduler.getNumQueuedContainers());
|
|
|
|
+
|
|
|
|
+ ContainerQueuingLimit containerQueuingLimit = ContainerQueuingLimit
|
|
|
|
+ .newInstance();
|
|
|
|
+ containerQueuingLimit.setMaxQueueLength(2);
|
|
|
|
+ containerScheduler.updateQueuingLimit(containerQueuingLimit);
|
|
|
|
+ numTries = 30;
|
|
|
|
+ while ((containerScheduler.getNumQueuedContainers() > 2) &&
|
|
|
|
+ (numTries-- > 0)) {
|
|
|
|
+ Thread.sleep(100);
|
|
|
|
+ }
|
|
|
|
+ Assert.assertEquals(2, containerScheduler.getNumQueuedContainers());
|
|
|
|
+
|
|
|
|
+ List<ContainerId> statList = new ArrayList<ContainerId>();
|
|
|
|
+ for (int i = 1; i < 7; i++) {
|
|
|
|
+ statList.add(createContainerId(i));
|
|
|
|
+ }
|
|
|
|
+ GetContainerStatusesRequest statRequest =
|
|
|
|
+ GetContainerStatusesRequest.newInstance(statList);
|
|
|
|
+ List<ContainerStatus> containerStatuses = containerManager
|
|
|
|
+ .getContainerStatuses(statRequest).getContainerStatuses();
|
|
|
|
+
|
|
|
|
+ int deQueuedContainers = 0;
|
|
|
|
+ int numQueuedOppContainers = 0;
|
|
|
|
+ for (ContainerStatus status : containerStatuses) {
|
|
|
|
+ if (status.getExecutionType() == ExecutionType.OPPORTUNISTIC) {
|
|
|
|
+ if (status.getDiagnostics().contains(
|
|
|
|
+ "Container De-queued to meet NM queuing limits")) {
|
|
|
|
+ deQueuedContainers++;
|
|
|
|
+ }
|
|
|
|
+ if (status.getState() ==
|
|
|
|
+ org.apache.hadoop.yarn.api.records.ContainerState.SCHEDULED) {
|
|
|
|
+ numQueuedOppContainers++;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ Assert.assertEquals(4, deQueuedContainers);
|
|
|
|
+ Assert.assertEquals(2, numQueuedOppContainers);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 1. Submit a long running GUARANTEED container to hog all NM resources.
|
|
|
|
+ * 2. Submit 2 OPPORTUNISTIC containers, both of which will be queued.
|
|
|
|
+ * 3. Send Stop Container to one of the queued containers.
|
|
|
|
+ * 4. Ensure container is removed from the queue.
|
|
|
|
+ * @throws Exception
|
|
|
|
+ */
|
|
|
|
+ @Test
|
|
|
|
+ public void testContainerDeQueuedAfterAMKill() throws Exception {
|
|
|
|
+ containerManager.start();
|
|
|
|
+
|
|
|
|
+ ContainerLaunchContext containerLaunchContext =
|
|
|
|
+ recordFactory.newRecordInstance(ContainerLaunchContext.class);
|
|
|
|
+ containerLaunchContext.setCommands(Arrays.asList("sleep 100"));
|
|
|
|
+
|
|
|
|
+ List<StartContainerRequest> list = new ArrayList<>();
|
|
|
|
+ list.add(StartContainerRequest.newInstance(
|
|
|
|
+ containerLaunchContext,
|
|
|
|
+ createContainerToken(createContainerId(0), DUMMY_RM_IDENTIFIER,
|
|
|
|
+ context.getNodeId(),
|
|
|
|
+ user, BuilderUtils.newResource(2048, 1),
|
|
|
|
+ context.getContainerTokenSecretManager(), null,
|
|
|
|
+ ExecutionType.GUARANTEED)));
|
|
|
|
+
|
|
|
|
+ StartContainersRequest allRequests =
|
|
|
|
+ StartContainersRequest.newInstance(list);
|
|
|
|
+ containerManager.startContainers(allRequests);
|
|
|
|
+
|
|
|
|
+ list = new ArrayList<>();
|
|
|
|
+ list.add(StartContainerRequest.newInstance(
|
|
|
|
+ containerLaunchContext,
|
|
|
|
+ createContainerToken(createContainerId(1), DUMMY_RM_IDENTIFIER,
|
|
|
|
+ context.getNodeId(),
|
|
|
|
+ user, BuilderUtils.newResource(512, 1),
|
|
|
|
+ context.getContainerTokenSecretManager(), null,
|
|
|
|
+ ExecutionType.OPPORTUNISTIC)));
|
|
|
|
+ list.add(StartContainerRequest.newInstance(
|
|
|
|
+ containerLaunchContext,
|
|
|
|
+ createContainerToken(createContainerId(2), DUMMY_RM_IDENTIFIER,
|
|
|
|
+ context.getNodeId(),
|
|
|
|
+ user, BuilderUtils.newResource(512, 1),
|
|
|
|
+ context.getContainerTokenSecretManager(), null,
|
|
|
|
+ ExecutionType.OPPORTUNISTIC)));
|
|
|
|
+
|
|
|
|
+ allRequests = StartContainersRequest.newInstance(list);
|
|
|
|
+ containerManager.startContainers(allRequests);
|
|
|
|
+
|
|
|
|
+ ContainerScheduler containerScheduler =
|
|
|
|
+ containerManager.getContainerScheduler();
|
|
|
|
+ // Ensure both containers are properly queued.
|
|
|
|
+ int numTries = 30;
|
|
|
|
+ while ((containerScheduler.getNumQueuedContainers() < 2) &&
|
|
|
|
+ (numTries-- > 0)) {
|
|
|
|
+ Thread.sleep(100);
|
|
|
|
+ }
|
|
|
|
+ Assert.assertEquals(2, containerScheduler.getNumQueuedContainers());
|
|
|
|
+
|
|
|
|
+ containerManager.stopContainers(
|
|
|
|
+ StopContainersRequest.newInstance(Arrays.asList(createContainerId(2))));
|
|
|
|
+
|
|
|
|
+ numTries = 30;
|
|
|
|
+ while ((containerScheduler.getNumQueuedContainers() > 1) &&
|
|
|
|
+ (numTries-- > 0)) {
|
|
|
|
+ Thread.sleep(100);
|
|
|
|
+ }
|
|
|
|
+ Assert.assertEquals(1, containerScheduler.getNumQueuedContainers());
|
|
|
|
+ }
|
|
|
|
+
|
|
/**
|
|
/**
|
|
* Submit three OPPORTUNISTIC containers that can run concurrently, and one
|
|
* Submit three OPPORTUNISTIC containers that can run concurrently, and one
|
|
* GUARANTEED that needs to kill two of the OPPORTUNISTIC for it to run.
|
|
* GUARANTEED that needs to kill two of the OPPORTUNISTIC for it to run.
|
|
@@ -427,7 +618,6 @@ public class TestQueuingContainerManager extends BaseContainerManagerTest {
|
|
*/
|
|
*/
|
|
@Test
|
|
@Test
|
|
public void testKillMultipleOpportunisticContainers() throws Exception {
|
|
public void testKillMultipleOpportunisticContainers() throws Exception {
|
|
- shouldDeleteWait = true;
|
|
|
|
containerManager.start();
|
|
containerManager.start();
|
|
|
|
|
|
ContainerLaunchContext containerLaunchContext =
|
|
ContainerLaunchContext containerLaunchContext =
|
|
@@ -455,6 +645,12 @@ public class TestQueuingContainerManager extends BaseContainerManagerTest {
|
|
user, BuilderUtils.newResource(512, 1),
|
|
user, BuilderUtils.newResource(512, 1),
|
|
context.getContainerTokenSecretManager(), null,
|
|
context.getContainerTokenSecretManager(), null,
|
|
ExecutionType.OPPORTUNISTIC)));
|
|
ExecutionType.OPPORTUNISTIC)));
|
|
|
|
+
|
|
|
|
+ StartContainersRequest allRequests =
|
|
|
|
+ StartContainersRequest.newInstance(list);
|
|
|
|
+ containerManager.startContainers(allRequests);
|
|
|
|
+
|
|
|
|
+ list = new ArrayList<>();
|
|
list.add(StartContainerRequest.newInstance(
|
|
list.add(StartContainerRequest.newInstance(
|
|
containerLaunchContext,
|
|
containerLaunchContext,
|
|
createContainerToken(createContainerId(3), DUMMY_RM_IDENTIFIER,
|
|
createContainerToken(createContainerId(3), DUMMY_RM_IDENTIFIER,
|
|
@@ -463,8 +659,7 @@ public class TestQueuingContainerManager extends BaseContainerManagerTest {
|
|
context.getContainerTokenSecretManager(), null,
|
|
context.getContainerTokenSecretManager(), null,
|
|
ExecutionType.GUARANTEED)));
|
|
ExecutionType.GUARANTEED)));
|
|
|
|
|
|
- StartContainersRequest allRequests =
|
|
|
|
- StartContainersRequest.newInstance(list);
|
|
|
|
|
|
+ allRequests = StartContainersRequest.newInstance(list);
|
|
containerManager.startContainers(allRequests);
|
|
containerManager.startContainers(allRequests);
|
|
|
|
|
|
BaseContainerManagerTest.waitForNMContainerState(
|
|
BaseContainerManagerTest.waitForNMContainerState(
|
|
@@ -486,7 +681,77 @@ public class TestQueuingContainerManager extends BaseContainerManagerTest {
|
|
.getContainerStatuses(statRequest).getContainerStatuses();
|
|
.getContainerStatuses(statRequest).getContainerStatuses();
|
|
for (ContainerStatus status : containerStatuses) {
|
|
for (ContainerStatus status : containerStatuses) {
|
|
if (status.getDiagnostics().contains(
|
|
if (status.getDiagnostics().contains(
|
|
- "Container killed by the ApplicationMaster")) {
|
|
|
|
|
|
+ "Container Killed to make room for Guaranteed Container")) {
|
|
|
|
+ killedContainers++;
|
|
|
|
+ }
|
|
|
|
+ System.out.println("\nStatus : [" + status + "]\n");
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ Assert.assertEquals(2, killedContainers);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * Submit four OPPORTUNISTIC containers that can run concurrently, and then
|
|
|
|
+ * two GUARANTEED that needs to kill Exactly two of the OPPORTUNISTIC for
|
|
|
|
+ * it to run. Make sure only 2 are killed.
|
|
|
|
+ * @throws Exception
|
|
|
|
+ */
|
|
|
|
+ @Test
|
|
|
|
+ public void testKillOnlyRequiredOpportunisticContainers() throws Exception {
|
|
|
|
+ containerManager.start();
|
|
|
|
+
|
|
|
|
+ ContainerLaunchContext containerLaunchContext =
|
|
|
|
+ recordFactory.newRecordInstance(ContainerLaunchContext.class);
|
|
|
|
+
|
|
|
|
+ List<StartContainerRequest> list = new ArrayList<>();
|
|
|
|
+ // Fill NM with Opportunistic containers
|
|
|
|
+ for (int i = 0; i < 4; i++) {
|
|
|
|
+ list.add(StartContainerRequest.newInstance(
|
|
|
|
+ containerLaunchContext,
|
|
|
|
+ createContainerToken(createContainerId(i), DUMMY_RM_IDENTIFIER,
|
|
|
|
+ context.getNodeId(),
|
|
|
|
+ user, BuilderUtils.newResource(512, 1),
|
|
|
|
+ context.getContainerTokenSecretManager(), null,
|
|
|
|
+ ExecutionType.OPPORTUNISTIC)));
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ StartContainersRequest allRequests =
|
|
|
|
+ StartContainersRequest.newInstance(list);
|
|
|
|
+ containerManager.startContainers(allRequests);
|
|
|
|
+
|
|
|
|
+ list = new ArrayList<>();
|
|
|
|
+ // Now ask for two Guaranteed containers
|
|
|
|
+ for (int i = 4; i < 6; i++) {
|
|
|
|
+ list.add(StartContainerRequest.newInstance(
|
|
|
|
+ containerLaunchContext,
|
|
|
|
+ createContainerToken(createContainerId(i), DUMMY_RM_IDENTIFIER,
|
|
|
|
+ context.getNodeId(),
|
|
|
|
+ user, BuilderUtils.newResource(512, 1),
|
|
|
|
+ context.getContainerTokenSecretManager(), null,
|
|
|
|
+ ExecutionType.GUARANTEED)));
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ allRequests = StartContainersRequest.newInstance(list);
|
|
|
|
+ containerManager.startContainers(allRequests);
|
|
|
|
+
|
|
|
|
+ BaseContainerManagerTest.waitForNMContainerState(containerManager,
|
|
|
|
+ createContainerId(0), ContainerState.DONE, 40);
|
|
|
|
+ Thread.sleep(5000);
|
|
|
|
+
|
|
|
|
+ // Get container statuses. Container 0 should be killed, container 1
|
|
|
|
+ // should be queued and container 2 should be running.
|
|
|
|
+ int killedContainers = 0;
|
|
|
|
+ List<ContainerId> statList = new ArrayList<ContainerId>();
|
|
|
|
+ for (int i = 0; i < 6; i++) {
|
|
|
|
+ statList.add(createContainerId(i));
|
|
|
|
+ }
|
|
|
|
+ GetContainerStatusesRequest statRequest =
|
|
|
|
+ GetContainerStatusesRequest.newInstance(statList);
|
|
|
|
+ List<ContainerStatus> containerStatuses = containerManager
|
|
|
|
+ .getContainerStatuses(statRequest).getContainerStatuses();
|
|
|
|
+ for (ContainerStatus status : containerStatuses) {
|
|
|
|
+ if (status.getDiagnostics().contains(
|
|
|
|
+ "Container Killed to make room for Guaranteed Container")) {
|
|
killedContainers++;
|
|
killedContainers++;
|
|
}
|
|
}
|
|
System.out.println("\nStatus : [" + status + "]\n");
|
|
System.out.println("\nStatus : [" + status + "]\n");
|
|
@@ -502,7 +767,6 @@ public class TestQueuingContainerManager extends BaseContainerManagerTest {
|
|
*/
|
|
*/
|
|
@Test
|
|
@Test
|
|
public void testStopQueuedContainer() throws Exception {
|
|
public void testStopQueuedContainer() throws Exception {
|
|
- shouldDeleteWait = true;
|
|
|
|
containerManager.start();
|
|
containerManager.start();
|
|
|
|
|
|
ContainerLaunchContext containerLaunchContext =
|
|
ContainerLaunchContext containerLaunchContext =
|
|
@@ -553,7 +817,7 @@ public class TestQueuingContainerManager extends BaseContainerManagerTest {
|
|
org.apache.hadoop.yarn.api.records.ContainerState.RUNNING) {
|
|
org.apache.hadoop.yarn.api.records.ContainerState.RUNNING) {
|
|
runningContainersNo++;
|
|
runningContainersNo++;
|
|
} else if (status.getState() ==
|
|
} else if (status.getState() ==
|
|
- org.apache.hadoop.yarn.api.records.ContainerState.QUEUED) {
|
|
|
|
|
|
+ org.apache.hadoop.yarn.api.records.ContainerState.SCHEDULED) {
|
|
queuedContainersNo++;
|
|
queuedContainersNo++;
|
|
}
|
|
}
|
|
System.out.println("\nStatus : [" + status + "]\n");
|
|
System.out.println("\nStatus : [" + status + "]\n");
|
|
@@ -574,23 +838,35 @@ public class TestQueuingContainerManager extends BaseContainerManagerTest {
|
|
for (int i = 0; i < 3; i++) {
|
|
for (int i = 0; i < 3; i++) {
|
|
statList.add(createContainerId(i));
|
|
statList.add(createContainerId(i));
|
|
}
|
|
}
|
|
|
|
+
|
|
statRequest = GetContainerStatusesRequest.newInstance(statList);
|
|
statRequest = GetContainerStatusesRequest.newInstance(statList);
|
|
- containerStatuses = containerManager.getContainerStatuses(statRequest)
|
|
|
|
- .getContainerStatuses();
|
|
|
|
- for (ContainerStatus status : containerStatuses) {
|
|
|
|
- if (status.getContainerId().equals(createContainerId(0))) {
|
|
|
|
- Assert.assertEquals(
|
|
|
|
- org.apache.hadoop.yarn.api.records.ContainerState.RUNNING,
|
|
|
|
- status.getState());
|
|
|
|
- } else if (status.getContainerId().equals(createContainerId(1))) {
|
|
|
|
- Assert.assertTrue(status.getDiagnostics().contains(
|
|
|
|
- "Queued container request removed"));
|
|
|
|
- } else if (status.getContainerId().equals(createContainerId(2))) {
|
|
|
|
- Assert.assertEquals(
|
|
|
|
- org.apache.hadoop.yarn.api.records.ContainerState.QUEUED,
|
|
|
|
- status.getState());
|
|
|
|
|
|
+ HashMap<org.apache.hadoop.yarn.api.records.ContainerState, ContainerStatus>
|
|
|
|
+ map = new HashMap<>();
|
|
|
|
+ for (int i=0; i < 10; i++) {
|
|
|
|
+ containerStatuses = containerManager.getContainerStatuses(statRequest)
|
|
|
|
+ .getContainerStatuses();
|
|
|
|
+ for (ContainerStatus status : containerStatuses) {
|
|
|
|
+ System.out.println("\nStatus : [" + status + "]\n");
|
|
|
|
+ map.put(status.getState(), status);
|
|
|
|
+ if (map.containsKey(
|
|
|
|
+ org.apache.hadoop.yarn.api.records.ContainerState.RUNNING) &&
|
|
|
|
+ map.containsKey(
|
|
|
|
+ org.apache.hadoop.yarn.api.records.ContainerState.SCHEDULED) &&
|
|
|
|
+ map.containsKey(
|
|
|
|
+ org.apache.hadoop.yarn.api.records.ContainerState.COMPLETE)) {
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+ Thread.sleep(1000);
|
|
}
|
|
}
|
|
- System.out.println("\nStatus : [" + status + "]\n");
|
|
|
|
}
|
|
}
|
|
|
|
+ Assert.assertEquals(createContainerId(0),
|
|
|
|
+ map.get(org.apache.hadoop.yarn.api.records.ContainerState.RUNNING)
|
|
|
|
+ .getContainerId());
|
|
|
|
+ Assert.assertEquals(createContainerId(1),
|
|
|
|
+ map.get(org.apache.hadoop.yarn.api.records.ContainerState.COMPLETE)
|
|
|
|
+ .getContainerId());
|
|
|
|
+ Assert.assertEquals(createContainerId(2),
|
|
|
|
+ map.get(org.apache.hadoop.yarn.api.records.ContainerState.SCHEDULED)
|
|
|
|
+ .getContainerId());
|
|
}
|
|
}
|
|
}
|
|
}
|