YARN-396. Rationalize AllocateResponse in RM Scheduler API. Contributed by Zhijie Shen.

git-svn-id: https://svn.apache.org/repos/asf/hadoop/common/trunk@1459040 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Hitesh Shah 2013-03-20 20:44:35 +00:00
parent f7df0cb7df
commit 1bd345d6e3
27 changed files with 518 additions and 689 deletions

View File

@ -38,7 +38,6 @@
import org.apache.hadoop.yarn.YarnException; import org.apache.hadoop.yarn.YarnException;
import org.apache.hadoop.yarn.api.protocolrecords.AllocateRequest; import org.apache.hadoop.yarn.api.protocolrecords.AllocateRequest;
import org.apache.hadoop.yarn.api.protocolrecords.AllocateResponse; import org.apache.hadoop.yarn.api.protocolrecords.AllocateResponse;
import org.apache.hadoop.yarn.api.records.AMResponse;
import org.apache.hadoop.yarn.api.records.Container; import org.apache.hadoop.yarn.api.records.Container;
import org.apache.hadoop.yarn.api.records.ContainerId; import org.apache.hadoop.yarn.api.records.ContainerId;
import org.apache.hadoop.yarn.api.records.NodeId; import org.apache.hadoop.yarn.api.records.NodeId;
@ -100,10 +99,9 @@ protected synchronized void heartbeat() throws Exception {
this.applicationAttemptId, this.lastResponseID, super this.applicationAttemptId, this.lastResponseID, super
.getApplicationProgress(), new ArrayList<ResourceRequest>(), .getApplicationProgress(), new ArrayList<ResourceRequest>(),
new ArrayList<ContainerId>()); new ArrayList<ContainerId>());
AMResponse response; AllocateResponse allocateResponse;
try { try {
AllocateResponse allocateResponse = scheduler.allocate(allocateRequest); allocateResponse = scheduler.allocate(allocateRequest);
response = allocateResponse.getAMResponse();
// Reset retry count if no exception occurred. // Reset retry count if no exception occurred.
retrystartTime = System.currentTimeMillis(); retrystartTime = System.currentTimeMillis();
} catch (Exception e) { } catch (Exception e) {
@ -120,7 +118,7 @@ protected synchronized void heartbeat() throws Exception {
// continue to attempt to contact the RM. // continue to attempt to contact the RM.
throw e; throw e;
} }
if (response.getReboot()) { if (allocateResponse.getReboot()) {
LOG.info("Event from RM: shutting down Application Master"); LOG.info("Event from RM: shutting down Application Master");
// This can happen if the RM has been restarted. If it is in that state, // This can happen if the RM has been restarted. If it is in that state,
// this application must clean itself up. // this application must clean itself up.

View File

@ -59,7 +59,7 @@
import org.apache.hadoop.mapreduce.v2.app.job.event.TaskAttemptKillEvent; import org.apache.hadoop.mapreduce.v2.app.job.event.TaskAttemptKillEvent;
import org.apache.hadoop.util.StringInterner; import org.apache.hadoop.util.StringInterner;
import org.apache.hadoop.yarn.YarnException; import org.apache.hadoop.yarn.YarnException;
import org.apache.hadoop.yarn.api.records.AMResponse; import org.apache.hadoop.yarn.api.protocolrecords.AllocateResponse;
import org.apache.hadoop.yarn.api.records.Container; import org.apache.hadoop.yarn.api.records.Container;
import org.apache.hadoop.yarn.api.records.ContainerId; import org.apache.hadoop.yarn.api.records.ContainerId;
import org.apache.hadoop.yarn.api.records.ContainerStatus; import org.apache.hadoop.yarn.api.records.ContainerStatus;
@ -544,8 +544,9 @@ public void rampDownReduces(int rampDown) {
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
private List<Container> getResources() throws Exception { private List<Container> getResources() throws Exception {
int headRoom = getAvailableResources() != null ? getAvailableResources().getMemory() : 0;//first time it would be null int headRoom = getAvailableResources() != null
AMResponse response; ? getAvailableResources().getMemory() : 0;//first time it would be null
AllocateResponse response;
/* /*
* If contact with RM is lost, the AM will wait MR_AM_TO_RM_WAIT_INTERVAL_MS * If contact with RM is lost, the AM will wait MR_AM_TO_RM_WAIT_INTERVAL_MS
* milliseconds before aborting. During this interval, AM will still try * milliseconds before aborting. During this interval, AM will still try
@ -634,7 +635,7 @@ public TaskAttemptEvent createContainerFinishedEvent(ContainerStatus cont,
} }
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
private void handleUpdatedNodes(AMResponse response) { private void handleUpdatedNodes(AllocateResponse response) {
// send event to the job about on updated nodes // send event to the job about on updated nodes
List<NodeReport> updatedNodes = response.getUpdatedNodes(); List<NodeReport> updatedNodes = response.getUpdatedNodes();
if (!updatedNodes.isEmpty()) { if (!updatedNodes.isEmpty()) {

View File

@ -38,7 +38,6 @@
import org.apache.hadoop.yarn.YarnException; import org.apache.hadoop.yarn.YarnException;
import org.apache.hadoop.yarn.api.protocolrecords.AllocateRequest; import org.apache.hadoop.yarn.api.protocolrecords.AllocateRequest;
import org.apache.hadoop.yarn.api.protocolrecords.AllocateResponse; import org.apache.hadoop.yarn.api.protocolrecords.AllocateResponse;
import org.apache.hadoop.yarn.api.records.AMResponse;
import org.apache.hadoop.yarn.api.records.ContainerId; import org.apache.hadoop.yarn.api.records.ContainerId;
import org.apache.hadoop.yarn.api.records.Priority; import org.apache.hadoop.yarn.api.records.Priority;
import org.apache.hadoop.yarn.api.records.Resource; import org.apache.hadoop.yarn.api.records.Resource;
@ -146,30 +145,30 @@ public void init(Configuration conf) {
LOG.info("blacklistDisablePercent is " + blacklistDisablePercent); LOG.info("blacklistDisablePercent is " + blacklistDisablePercent);
} }
protected AMResponse makeRemoteRequest() throws YarnRemoteException { protected AllocateResponse makeRemoteRequest() throws YarnRemoteException {
AllocateRequest allocateRequest = BuilderUtils.newAllocateRequest( AllocateRequest allocateRequest = BuilderUtils.newAllocateRequest(
applicationAttemptId, lastResponseID, super.getApplicationProgress(), applicationAttemptId, lastResponseID, super.getApplicationProgress(),
new ArrayList<ResourceRequest>(ask), new ArrayList<ContainerId>( new ArrayList<ResourceRequest>(ask), new ArrayList<ContainerId>(
release)); release));
AllocateResponse allocateResponse = scheduler.allocate(allocateRequest); AllocateResponse allocateResponse = scheduler.allocate(allocateRequest);
AMResponse response = allocateResponse.getAMResponse(); lastResponseID = allocateResponse.getResponseId();
lastResponseID = response.getResponseId(); availableResources = allocateResponse.getAvailableResources();
availableResources = response.getAvailableResources();
lastClusterNmCount = clusterNmCount; lastClusterNmCount = clusterNmCount;
clusterNmCount = allocateResponse.getNumClusterNodes(); clusterNmCount = allocateResponse.getNumClusterNodes();
if (ask.size() > 0 || release.size() > 0) { if (ask.size() > 0 || release.size() > 0) {
LOG.info("getResources() for " + applicationId + ":" + " ask=" LOG.info("getResources() for " + applicationId + ":" + " ask="
+ ask.size() + " release= " + release.size() + " newContainers=" + ask.size() + " release= " + release.size() + " newContainers="
+ response.getAllocatedContainers().size() + " finishedContainers=" + allocateResponse.getAllocatedContainers().size()
+ response.getCompletedContainersStatuses().size() + " finishedContainers="
+ allocateResponse.getCompletedContainersStatuses().size()
+ " resourcelimit=" + availableResources + " knownNMs=" + " resourcelimit=" + availableResources + " knownNMs="
+ clusterNmCount); + clusterNmCount);
} }
ask.clear(); ask.clear();
release.clear(); release.clear();
return response; return allocateResponse;
} }
// May be incorrect if there's multiple NodeManagers running on a single host. // May be incorrect if there's multiple NodeManagers running on a single host.

View File

@ -40,7 +40,6 @@
import org.apache.hadoop.yarn.api.protocolrecords.FinishApplicationMasterResponse; import org.apache.hadoop.yarn.api.protocolrecords.FinishApplicationMasterResponse;
import org.apache.hadoop.yarn.api.protocolrecords.RegisterApplicationMasterRequest; import org.apache.hadoop.yarn.api.protocolrecords.RegisterApplicationMasterRequest;
import org.apache.hadoop.yarn.api.protocolrecords.RegisterApplicationMasterResponse; import org.apache.hadoop.yarn.api.protocolrecords.RegisterApplicationMasterResponse;
import org.apache.hadoop.yarn.api.records.AMResponse;
import org.apache.hadoop.yarn.api.records.Container; import org.apache.hadoop.yarn.api.records.Container;
import org.apache.hadoop.yarn.api.records.ContainerId; import org.apache.hadoop.yarn.api.records.ContainerId;
import org.apache.hadoop.yarn.api.records.NodeId; import org.apache.hadoop.yarn.api.records.NodeId;
@ -248,10 +247,8 @@ public AllocateResponse allocate(AllocateRequest request)
} }
} }
AMResponse amResponse = Records.newRecord(AMResponse.class); response.setAllocatedContainers(containers);
amResponse.setAllocatedContainers(containers); response.setResponseId(request.getResponseId() + 1);
amResponse.setResponseId(request.getResponseId() + 1);
response.setAMResponse(amResponse);
response.setNumClusterNodes(350); response.setNumClusterNodes(350);
return response; return response;
} }

View File

@ -52,6 +52,9 @@ Release 2.0.5-beta - UNRELEASED
INCOMPATIBLE CHANGES INCOMPATIBLE CHANGES
YARN-396. Rationalize AllocateResponse in RM Scheduler API. (Zhijie Shen
via hitesh)
NEW FEATURES NEW FEATURES
IMPROVEMENTS IMPROVEMENTS

View File

@ -18,19 +18,23 @@
package org.apache.hadoop.yarn.api.protocolrecords; package org.apache.hadoop.yarn.api.protocolrecords;
import java.util.List;
import org.apache.hadoop.classification.InterfaceAudience.Private; import org.apache.hadoop.classification.InterfaceAudience.Private;
import org.apache.hadoop.classification.InterfaceAudience.Public; import org.apache.hadoop.classification.InterfaceAudience.Public;
import org.apache.hadoop.classification.InterfaceStability.Stable; import org.apache.hadoop.classification.InterfaceStability.Stable;
import org.apache.hadoop.classification.InterfaceStability.Unstable; import org.apache.hadoop.classification.InterfaceStability.Unstable;
import org.apache.hadoop.yarn.api.AMRMProtocol; import org.apache.hadoop.yarn.api.AMRMProtocol;
import org.apache.hadoop.yarn.api.records.AMResponse;
import org.apache.hadoop.yarn.api.records.Container; import org.apache.hadoop.yarn.api.records.Container;
import org.apache.hadoop.yarn.api.records.ContainerStatus;
import org.apache.hadoop.yarn.api.records.NodeReport;
import org.apache.hadoop.yarn.api.records.Resource;
/** /**
* <p>The response sent by the <code>ResourceManager</code> the * <p>The response sent by the <code>ResourceManager</code> the
* <code>ApplicationMaster</code> during resource negotiation.</p> * <code>ApplicationMaster</code> during resource negotiation.</p>
* *
* <p>The response, via {@link AMResponse}, includes: * <p>The response, includes:
* <ul> * <ul>
* <li>Response ID to track duplicate responses.</li> * <li>Response ID to track duplicate responses.</li>
* <li> * <li>
@ -42,6 +46,8 @@
* The available headroom for resources in the cluster for the * The available headroom for resources in the cluster for the
* application. * application.
* </li> * </li>
* <li>A list of nodes whose status has been updated.</li>
* <li>The number of available nodes in a cluster.</li>
* </ul> * </ul>
* </p> * </p>
* *
@ -51,17 +57,89 @@
@Stable @Stable
public interface AllocateResponse { public interface AllocateResponse {
/** /**
* Get the {@link AMResponse} sent by the <code>ResourceManager</code>. * Should the <code>ApplicationMaster</code> reboot for being horribly
* @return <code>AMResponse</code> sent by the <code>ResourceManager</code> * out-of-sync with the <code>ResourceManager</code> as deigned by
* {@link #getResponseId()}?
*
* @return <code>true</code> if the <code>ApplicationMaster</code> should
* reboot, <code>false</code> otherwise
*/ */
@Public @Public
@Stable @Stable
public abstract AMResponse getAMResponse(); public boolean getReboot();
@Private @Private
@Unstable @Unstable
public abstract void setAMResponse(AMResponse amResponse); public void setReboot(boolean reboot);
/**
* Get the <em>last response id</em>.
* @return <em>last response id</em>
*/
@Public
@Stable
public int getResponseId();
@Private
@Unstable
public void setResponseId(int responseId);
/**
* Get the list of <em>newly allocated</em> <code>Container</code> by the
* <code>ResourceManager</code>.
* @return list of <em>newly allocated</em> <code>Container</code>
*/
@Public
@Stable
public List<Container> getAllocatedContainers();
/**
* Set the list of <em>newly allocated</em> <code>Container</code> by the
* <code>ResourceManager</code>.
* @param containers list of <em>newly allocated</em> <code>Container</code>
*/
@Public
@Stable
public void setAllocatedContainers(List<Container> containers);
/**
* Get the <em>available headroom</em> for resources in the cluster for the
* application.
* @return limit of available headroom for resources in the cluster for the
* application
*/
@Public
@Stable
public Resource getAvailableResources();
@Private
@Unstable
public void setAvailableResources(Resource limit);
/**
* Get the list of <em>completed containers' statuses</em>.
* @return the list of <em>completed containers' statuses</em>
*/
@Public
@Stable
public List<ContainerStatus> getCompletedContainersStatuses();
@Private
@Unstable
public void setCompletedContainersStatuses(List<ContainerStatus> containers);
/**
* Get the list of <em>updated <code>NodeReport</code>s</em>. Updates could
* be changes in health, availability etc of the nodes.
* @return The delta of updated nodes since the last response
*/
@Public
@Unstable
public List<NodeReport> getUpdatedNodes();
@Private
@Unstable
public void setUpdatedNodes(final List<NodeReport> updatedNodes);
/** /**
* Get the number of hosts available on the cluster. * Get the number of hosts available on the cluster.

View File

@ -19,11 +19,24 @@
package org.apache.hadoop.yarn.api.protocolrecords.impl.pb; package org.apache.hadoop.yarn.api.protocolrecords.impl.pb;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import org.apache.hadoop.yarn.api.protocolrecords.AllocateResponse; import org.apache.hadoop.yarn.api.protocolrecords.AllocateResponse;
import org.apache.hadoop.yarn.api.records.AMResponse; import org.apache.hadoop.yarn.api.records.Container;
import org.apache.hadoop.yarn.api.records.ContainerStatus;
import org.apache.hadoop.yarn.api.records.NodeReport;
import org.apache.hadoop.yarn.api.records.ProtoBase; import org.apache.hadoop.yarn.api.records.ProtoBase;
import org.apache.hadoop.yarn.api.records.impl.pb.AMResponsePBImpl; import org.apache.hadoop.yarn.api.records.Resource;
import org.apache.hadoop.yarn.proto.YarnProtos.AMResponseProto; import org.apache.hadoop.yarn.api.records.impl.pb.ContainerPBImpl;
import org.apache.hadoop.yarn.api.records.impl.pb.ContainerStatusPBImpl;
import org.apache.hadoop.yarn.api.records.impl.pb.NodeReportPBImpl;
import org.apache.hadoop.yarn.api.records.impl.pb.ResourcePBImpl;
import org.apache.hadoop.yarn.proto.YarnProtos.ContainerProto;
import org.apache.hadoop.yarn.proto.YarnProtos.ContainerStatusProto;
import org.apache.hadoop.yarn.proto.YarnProtos.NodeReportProto;
import org.apache.hadoop.yarn.proto.YarnProtos.ResourceProto;
import org.apache.hadoop.yarn.proto.YarnServiceProtos.AllocateResponseProto; import org.apache.hadoop.yarn.proto.YarnServiceProtos.AllocateResponseProto;
import org.apache.hadoop.yarn.proto.YarnServiceProtos.AllocateResponseProtoOrBuilder; import org.apache.hadoop.yarn.proto.YarnServiceProtos.AllocateResponseProtoOrBuilder;
@ -35,7 +48,12 @@ public class AllocateResponsePBImpl extends ProtoBase<AllocateResponseProto>
AllocateResponseProto.Builder builder = null; AllocateResponseProto.Builder builder = null;
boolean viaProto = false; boolean viaProto = false;
private AMResponse amResponse; Resource limit;
private List<Container> allocatedContainers = null;
private List<ContainerStatus> completedContainersStatuses = null;
private List<NodeReport> updatedNodes = null;
public AllocateResponsePBImpl() { public AllocateResponsePBImpl() {
@ -47,20 +65,38 @@ public AllocateResponsePBImpl(AllocateResponseProto proto) {
viaProto = true; viaProto = true;
} }
public AllocateResponseProto getProto() { public synchronized AllocateResponseProto getProto() {
mergeLocalToProto(); mergeLocalToProto();
proto = viaProto ? proto : builder.build(); proto = viaProto ? proto : builder.build();
viaProto = true; viaProto = true;
return proto; return proto;
} }
private void mergeLocalToBuilder() { private synchronized void mergeLocalToBuilder() {
if (this.amResponse != null) { if (this.allocatedContainers != null) {
builder.setAMResponse(convertToProtoFormat(this.amResponse)); builder.clearAllocatedContainers();
Iterable<ContainerProto> iterable =
getProtoIterable(this.allocatedContainers);
builder.addAllAllocatedContainers(iterable);
}
if (this.completedContainersStatuses != null) {
builder.clearCompletedContainerStatuses();
Iterable<ContainerStatusProto> iterable =
getContainerStatusProtoIterable(this.completedContainersStatuses);
builder.addAllCompletedContainerStatuses(iterable);
}
if (this.updatedNodes != null) {
builder.clearUpdatedNodes();
Iterable<NodeReportProto> iterable =
getNodeReportProtoIterable(this.updatedNodes);
builder.addAllUpdatedNodes(iterable);
}
if (this.limit != null) {
builder.setLimit(convertToProtoFormat(this.limit));
} }
} }
private void mergeLocalToProto() { private synchronized void mergeLocalToProto() {
if (viaProto) if (viaProto)
maybeInitBuilder(); maybeInitBuilder();
mergeLocalToBuilder(); mergeLocalToBuilder();
@ -68,53 +104,293 @@ private void mergeLocalToProto() {
viaProto = true; viaProto = true;
} }
private void maybeInitBuilder() { private synchronized void maybeInitBuilder() {
if (viaProto || builder == null) { if (viaProto || builder == null) {
builder = AllocateResponseProto.newBuilder(proto); builder = AllocateResponseProto.newBuilder(proto);
} }
viaProto = false; viaProto = false;
} }
@Override
public synchronized boolean getReboot() {
AllocateResponseProtoOrBuilder p = viaProto ? proto : builder;
return (p.getReboot());
}
@Override @Override
public AMResponse getAMResponse() { public synchronized void setReboot(boolean reboot) {
maybeInitBuilder();
builder.setReboot((reboot));
}
@Override
public synchronized int getResponseId() {
AllocateResponseProtoOrBuilder p = viaProto ? proto : builder; AllocateResponseProtoOrBuilder p = viaProto ? proto : builder;
if (this.amResponse != null) { return (p.getResponseId());
return this.amResponse; }
@Override
public synchronized void setResponseId(int responseId) {
maybeInitBuilder();
builder.setResponseId((responseId));
}
@Override
public synchronized Resource getAvailableResources() {
if (this.limit != null) {
return this.limit;
} }
if (!p.hasAMResponse()) {
AllocateResponseProtoOrBuilder p = viaProto ? proto : builder;
if (!p.hasLimit()) {
return null; return null;
} }
this.amResponse= convertFromProtoFormat(p.getAMResponse()); this.limit = convertFromProtoFormat(p.getLimit());
return this.amResponse; return this.limit;
} }
@Override @Override
public void setAMResponse(AMResponse aMResponse) { public synchronized void setAvailableResources(Resource limit) {
maybeInitBuilder(); maybeInitBuilder();
if (aMResponse == null) if (limit == null)
builder.clearAMResponse(); builder.clearLimit();
this.amResponse = aMResponse; this.limit = limit;
} }
@Override @Override
public int getNumClusterNodes() { public synchronized List<NodeReport> getUpdatedNodes() {
initLocalNewNodeReportList();
return this.updatedNodes;
}
@Override
public synchronized void setUpdatedNodes(
final List<NodeReport> updatedNodes) {
if (updatedNodes == null) {
this.updatedNodes.clear();
return;
}
this.updatedNodes = new ArrayList<NodeReport>(updatedNodes.size());
this.updatedNodes.addAll(updatedNodes);
}
@Override
public synchronized List<Container> getAllocatedContainers() {
initLocalNewContainerList();
return this.allocatedContainers;
}
@Override
public synchronized void setAllocatedContainers(
final List<Container> containers) {
if (containers == null)
return;
// this looks like a bug because it results in append and not set
initLocalNewContainerList();
allocatedContainers.addAll(containers);
}
//// Finished containers
@Override
public synchronized List<ContainerStatus> getCompletedContainersStatuses() {
initLocalFinishedContainerList();
return this.completedContainersStatuses;
}
@Override
public synchronized void setCompletedContainersStatuses(
final List<ContainerStatus> containers) {
if (containers == null)
return;
initLocalFinishedContainerList();
completedContainersStatuses.addAll(containers);
}
@Override
public synchronized int getNumClusterNodes() {
AllocateResponseProtoOrBuilder p = viaProto ? proto : builder; AllocateResponseProtoOrBuilder p = viaProto ? proto : builder;
return p.getNumClusterNodes(); return p.getNumClusterNodes();
} }
@Override @Override
public void setNumClusterNodes(int numNodes) { public synchronized void setNumClusterNodes(int numNodes) {
maybeInitBuilder(); maybeInitBuilder();
builder.setNumClusterNodes(numNodes); builder.setNumClusterNodes(numNodes);
} }
// Once this is called. updatedNodes will never be null - until a getProto is
// called.
private synchronized void initLocalNewNodeReportList() {
if (this.updatedNodes != null) {
return;
}
AllocateResponseProtoOrBuilder p = viaProto ? proto : builder;
List<NodeReportProto> list = p.getUpdatedNodesList();
updatedNodes = new ArrayList<NodeReport>(list.size());
private AMResponsePBImpl convertFromProtoFormat(AMResponseProto p) { for (NodeReportProto n : list) {
return new AMResponsePBImpl(p); updatedNodes.add(convertFromProtoFormat(n));
}
} }
private AMResponseProto convertToProtoFormat(AMResponse t) { // Once this is called. containerList will never be null - until a getProto
return ((AMResponsePBImpl)t).getProto(); // is called.
private synchronized void initLocalNewContainerList() {
if (this.allocatedContainers != null) {
return;
}
AllocateResponseProtoOrBuilder p = viaProto ? proto : builder;
List<ContainerProto> list = p.getAllocatedContainersList();
allocatedContainers = new ArrayList<Container>();
for (ContainerProto c : list) {
allocatedContainers.add(convertFromProtoFormat(c));
}
} }
private synchronized Iterable<ContainerProto> getProtoIterable(
final List<Container> newContainersList) {
maybeInitBuilder();
return new Iterable<ContainerProto>() {
@Override
public synchronized Iterator<ContainerProto> iterator() {
return new Iterator<ContainerProto>() {
Iterator<Container> iter = newContainersList.iterator();
@Override
public synchronized boolean hasNext() {
return iter.hasNext();
}
@Override
public synchronized ContainerProto next() {
return convertToProtoFormat(iter.next());
}
@Override
public synchronized void remove() {
throw new UnsupportedOperationException();
}
};
}
};
}
private synchronized Iterable<ContainerStatusProto>
getContainerStatusProtoIterable(
final List<ContainerStatus> newContainersList) {
maybeInitBuilder();
return new Iterable<ContainerStatusProto>() {
@Override
public synchronized Iterator<ContainerStatusProto> iterator() {
return new Iterator<ContainerStatusProto>() {
Iterator<ContainerStatus> iter = newContainersList.iterator();
@Override
public synchronized boolean hasNext() {
return iter.hasNext();
}
@Override
public synchronized ContainerStatusProto next() {
return convertToProtoFormat(iter.next());
}
@Override
public synchronized void remove() {
throw new UnsupportedOperationException();
}
};
}
};
}
private synchronized Iterable<NodeReportProto>
getNodeReportProtoIterable(
final List<NodeReport> newNodeReportsList) {
maybeInitBuilder();
return new Iterable<NodeReportProto>() {
@Override
public synchronized Iterator<NodeReportProto> iterator() {
return new Iterator<NodeReportProto>() {
Iterator<NodeReport> iter = newNodeReportsList.iterator();
@Override
public synchronized boolean hasNext() {
return iter.hasNext();
}
@Override
public synchronized NodeReportProto next() {
return convertToProtoFormat(iter.next());
}
@Override
public synchronized void remove() {
throw new UnsupportedOperationException();
}
};
}
};
}
// Once this is called. containerList will never be null - until a getProto
// is called.
private synchronized void initLocalFinishedContainerList() {
if (this.completedContainersStatuses != null) {
return;
}
AllocateResponseProtoOrBuilder p = viaProto ? proto : builder;
List<ContainerStatusProto> list = p.getCompletedContainerStatusesList();
completedContainersStatuses = new ArrayList<ContainerStatus>();
for (ContainerStatusProto c : list) {
completedContainersStatuses.add(convertFromProtoFormat(c));
}
}
private synchronized NodeReportPBImpl convertFromProtoFormat(
NodeReportProto p) {
return new NodeReportPBImpl(p);
}
private synchronized NodeReportProto convertToProtoFormat(NodeReport t) {
return ((NodeReportPBImpl)t).getProto();
}
private synchronized ContainerPBImpl convertFromProtoFormat(
ContainerProto p) {
return new ContainerPBImpl(p);
}
private synchronized ContainerProto convertToProtoFormat(Container t) {
return ((ContainerPBImpl)t).getProto();
}
private synchronized ContainerStatusPBImpl convertFromProtoFormat(
ContainerStatusProto p) {
return new ContainerStatusPBImpl(p);
}
private synchronized ContainerStatusProto convertToProtoFormat(
ContainerStatus t) {
return ((ContainerStatusPBImpl)t).getProto();
}
private synchronized ResourcePBImpl convertFromProtoFormat(ResourceProto p) {
return new ResourcePBImpl(p);
}
private synchronized ResourceProto convertToProtoFormat(Resource r) {
return ((ResourcePBImpl) r).getProto();
}
} }

View File

@ -93,7 +93,8 @@ private void maybeInitBuilder() {
viaProto = false; viaProto = false;
} }
//Once this is called. containerList will never be null - untill a getProto is called. // Once this is called. containerList will never be null - until a getProto
// is called.
private void initLocalApplicationsList() { private void initLocalApplicationsList() {
if (this.applicationList != null) { if (this.applicationList != null) {
return; return;

View File

@ -92,7 +92,8 @@ private void maybeInitBuilder() {
viaProto = false; viaProto = false;
} }
//Once this is called. containerList will never be null - untill a getProto is called. // Once this is called. containerList will never be null - until a getProto
// is called.
private void initLocalNodeManagerInfosList() { private void initLocalNodeManagerInfosList() {
if (this.nodeManagerInfoList != null) { if (this.nodeManagerInfoList != null) {
return; return;

View File

@ -94,7 +94,8 @@ private void maybeInitBuilder() {
viaProto = false; viaProto = false;
} }
//Once this is called. containerList will never be null - untill a getProto is called. // Once this is called. containerList will never be null - until a getProto
// is called.
private void initLocalQueueUserAclsList() { private void initLocalQueueUserAclsList() {
if (this.queueUserAclsInfoList != null) { if (this.queueUserAclsInfoList != null) {
return; return;

View File

@ -1,138 +0,0 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.hadoop.yarn.api.records;
import java.util.List;
import org.apache.hadoop.classification.InterfaceAudience.Private;
import org.apache.hadoop.classification.InterfaceAudience.Public;
import org.apache.hadoop.classification.InterfaceStability.Stable;
import org.apache.hadoop.classification.InterfaceStability.Unstable;
import org.apache.hadoop.yarn.api.AMRMProtocol;
import org.apache.hadoop.yarn.api.protocolrecords.AllocateRequest;
/**
* <p>The response sent by the <code>ResourceManager</code> the
* <code>ApplicationMaster</code> during resource negotiation.</p>
*
* <p>The response includes:
* <ul>
* <li>Response ID to track duplicate responses.</li>
* <li>
* A reboot flag to let the <code>ApplicationMaster</code> know that its
* horribly out of sync and needs to reboot.</li>
* <li>A list of newly allocated {@link Container}.</li>
* <li>A list of completed {@link Container}.</li>
* <li>
* The available headroom for resources in the cluster for the
* application.
* </li>
* </ul>
* </p>
*
* @see AMRMProtocol#allocate(AllocateRequest)
*/
@Public
@Unstable
public interface AMResponse {
/**
* Should the <code>ApplicationMaster</code> reboot for being horribly
* out-of-sync with the <code>ResourceManager</code> as deigned by
* {@link #getResponseId()}?
*
* @return <code>true</code> if the <code>ApplicationMaster</code> should
* reboot, <code>false</code> otherwise
*/
@Public
@Stable
public boolean getReboot();
@Private
@Unstable
public void setReboot(boolean reboot);
/**
* Get the <em>last response id</em>.
* @return <em>last response id</em>
*/
@Public
@Stable
public int getResponseId();
@Private
@Unstable
public void setResponseId(int responseId);
/**
* Get the list of <em>newly allocated</em> <code>Container</code> by the
* <code>ResourceManager</code>.
* @return list of <em>newly allocated</em> <code>Container</code>
*/
@Public
@Stable
public List<Container> getAllocatedContainers();
/**
* Set the list of <em>newly allocated</em> <code>Container</code> by the
* <code>ResourceManager</code>.
* @param containers list of <em>newly allocated</em> <code>Container</code>
*/
@Public
@Stable
public void setAllocatedContainers(List<Container> containers);
/**
* Get the <em>available headroom</em> for resources in the cluster for the
* application.
* @return limit of available headroom for resources in the cluster for the
* application
*/
@Public
@Stable
public Resource getAvailableResources();
@Private
@Unstable
public void setAvailableResources(Resource limit);
/**
* Get the list of <em>completed containers' statuses</em>.
* @return the list of <em>completed containers' statuses</em>
*/
@Public
@Stable
public List<ContainerStatus> getCompletedContainersStatuses();
@Private
@Unstable
public void setCompletedContainersStatuses(List<ContainerStatus> containers);
/**
* Get the list of <em>updated <code>NodeReport</code>s</em>. Updates could be
* changes in health, availability etc of the nodes.
* @return The delta of updated nodes since the last response
*/
@Public
@Unstable
public List<NodeReport> getUpdatedNodes();
@Private
@Unstable
public void setUpdatedNodes(final List<NodeReport> updatedNodes);
}

View File

@ -1,373 +0,0 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.hadoop.yarn.api.records.impl.pb;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import org.apache.hadoop.yarn.api.records.AMResponse;
import org.apache.hadoop.yarn.api.records.Container;
import org.apache.hadoop.yarn.api.records.ContainerStatus;
import org.apache.hadoop.yarn.api.records.NodeReport;
import org.apache.hadoop.yarn.api.records.ProtoBase;
import org.apache.hadoop.yarn.api.records.Resource;
import org.apache.hadoop.yarn.proto.YarnProtos.AMResponseProto;
import org.apache.hadoop.yarn.proto.YarnProtos.AMResponseProtoOrBuilder;
import org.apache.hadoop.yarn.proto.YarnProtos.ContainerProto;
import org.apache.hadoop.yarn.proto.YarnProtos.ContainerStatusProto;
import org.apache.hadoop.yarn.proto.YarnProtos.NodeReportProto;
import org.apache.hadoop.yarn.proto.YarnProtos.ResourceProto;
public class AMResponsePBImpl extends ProtoBase<AMResponseProto> implements AMResponse {
AMResponseProto proto = AMResponseProto.getDefaultInstance();
AMResponseProto.Builder builder = null;
boolean viaProto = false;
Resource limit;
private List<Container> allocatedContainers = null;
private List<ContainerStatus> completedContainersStatuses = null;
// private boolean hasLocalContainerList = false;
private List<NodeReport> updatedNodes = null;
public AMResponsePBImpl() {
builder = AMResponseProto.newBuilder();
}
public AMResponsePBImpl(AMResponseProto proto) {
this.proto = proto;
viaProto = true;
}
public synchronized AMResponseProto getProto() {
mergeLocalToProto();
proto = viaProto ? proto : builder.build();
viaProto = true;
return proto;
}
private synchronized void mergeLocalToBuilder() {
if (this.allocatedContainers != null) {
builder.clearAllocatedContainers();
Iterable<ContainerProto> iterable =
getProtoIterable(this.allocatedContainers);
builder.addAllAllocatedContainers(iterable);
}
if (this.completedContainersStatuses != null) {
builder.clearCompletedContainerStatuses();
Iterable<ContainerStatusProto> iterable =
getContainerStatusProtoIterable(this.completedContainersStatuses);
builder.addAllCompletedContainerStatuses(iterable);
}
if (this.updatedNodes != null) {
builder.clearUpdatedNodes();
Iterable<NodeReportProto> iterable =
getNodeReportProtoIterable(this.updatedNodes);
builder.addAllUpdatedNodes(iterable);
}
if (this.limit != null) {
builder.setLimit(convertToProtoFormat(this.limit));
}
}
private synchronized void mergeLocalToProto() {
if (viaProto)
maybeInitBuilder();
mergeLocalToBuilder();
proto = builder.build();
viaProto = true;
}
private synchronized void maybeInitBuilder() {
if (viaProto || builder == null) {
builder = AMResponseProto.newBuilder(proto);
}
viaProto = false;
}
@Override
public synchronized boolean getReboot() {
AMResponseProtoOrBuilder p = viaProto ? proto : builder;
return (p.getReboot());
}
@Override
public synchronized void setReboot(boolean reboot) {
maybeInitBuilder();
builder.setReboot((reboot));
}
@Override
public synchronized int getResponseId() {
AMResponseProtoOrBuilder p = viaProto ? proto : builder;
return (p.getResponseId());
}
@Override
public synchronized void setResponseId(int responseId) {
maybeInitBuilder();
builder.setResponseId((responseId));
}
@Override
public synchronized Resource getAvailableResources() {
if (this.limit != null) {
return this.limit;
}
AMResponseProtoOrBuilder p = viaProto ? proto : builder;
if (!p.hasLimit()) {
return null;
}
this.limit = convertFromProtoFormat(p.getLimit());
return this.limit;
}
@Override
public synchronized void setAvailableResources(Resource limit) {
maybeInitBuilder();
if (limit == null)
builder.clearLimit();
this.limit = limit;
}
@Override
public synchronized List<NodeReport> getUpdatedNodes() {
initLocalNewNodeReportList();
return this.updatedNodes;
}
//Once this is called. updatedNodes will never be null - until a getProto is called.
private synchronized void initLocalNewNodeReportList() {
if (this.updatedNodes != null) {
return;
}
AMResponseProtoOrBuilder p = viaProto ? proto : builder;
List<NodeReportProto> list = p.getUpdatedNodesList();
updatedNodes = new ArrayList<NodeReport>(list.size());
for (NodeReportProto n : list) {
updatedNodes.add(convertFromProtoFormat(n));
}
}
@Override
public synchronized void setUpdatedNodes(final List<NodeReport> updatedNodes) {
if (updatedNodes == null) {
this.updatedNodes.clear();
return;
}
this.updatedNodes = new ArrayList<NodeReport>(updatedNodes.size());
this.updatedNodes.addAll(updatedNodes);
}
@Override
public synchronized List<Container> getAllocatedContainers() {
initLocalNewContainerList();
return this.allocatedContainers;
}
//Once this is called. containerList will never be null - until a getProto is called.
private synchronized void initLocalNewContainerList() {
if (this.allocatedContainers != null) {
return;
}
AMResponseProtoOrBuilder p = viaProto ? proto : builder;
List<ContainerProto> list = p.getAllocatedContainersList();
allocatedContainers = new ArrayList<Container>();
for (ContainerProto c : list) {
allocatedContainers.add(convertFromProtoFormat(c));
}
}
@Override
public synchronized void setAllocatedContainers(final List<Container> containers) {
if (containers == null)
return;
// this looks like a bug because it results in append and not set
initLocalNewContainerList();
allocatedContainers.addAll(containers);
}
private synchronized Iterable<ContainerProto> getProtoIterable(
final List<Container> newContainersList) {
maybeInitBuilder();
return new Iterable<ContainerProto>() {
@Override
public synchronized Iterator<ContainerProto> iterator() {
return new Iterator<ContainerProto>() {
Iterator<Container> iter = newContainersList.iterator();
@Override
public synchronized boolean hasNext() {
return iter.hasNext();
}
@Override
public synchronized ContainerProto next() {
return convertToProtoFormat(iter.next());
}
@Override
public synchronized void remove() {
throw new UnsupportedOperationException();
}
};
}
};
}
private synchronized Iterable<ContainerStatusProto>
getContainerStatusProtoIterable(
final List<ContainerStatus> newContainersList) {
maybeInitBuilder();
return new Iterable<ContainerStatusProto>() {
@Override
public synchronized Iterator<ContainerStatusProto> iterator() {
return new Iterator<ContainerStatusProto>() {
Iterator<ContainerStatus> iter = newContainersList.iterator();
@Override
public synchronized boolean hasNext() {
return iter.hasNext();
}
@Override
public synchronized ContainerStatusProto next() {
return convertToProtoFormat(iter.next());
}
@Override
public synchronized void remove() {
throw new UnsupportedOperationException();
}
};
}
};
}
private synchronized Iterable<NodeReportProto>
getNodeReportProtoIterable(
final List<NodeReport> newNodeReportsList) {
maybeInitBuilder();
return new Iterable<NodeReportProto>() {
@Override
public synchronized Iterator<NodeReportProto> iterator() {
return new Iterator<NodeReportProto>() {
Iterator<NodeReport> iter = newNodeReportsList.iterator();
@Override
public synchronized boolean hasNext() {
return iter.hasNext();
}
@Override
public synchronized NodeReportProto next() {
return convertToProtoFormat(iter.next());
}
@Override
public synchronized void remove() {
throw new UnsupportedOperationException();
}
};
}
};
}
//// Finished containers
@Override
public synchronized List<ContainerStatus> getCompletedContainersStatuses() {
initLocalFinishedContainerList();
return this.completedContainersStatuses;
}
//Once this is called. containerList will never be null - untill a getProto is called.
private synchronized void initLocalFinishedContainerList() {
if (this.completedContainersStatuses != null) {
return;
}
AMResponseProtoOrBuilder p = viaProto ? proto : builder;
List<ContainerStatusProto> list = p.getCompletedContainerStatusesList();
completedContainersStatuses = new ArrayList<ContainerStatus>();
for (ContainerStatusProto c : list) {
completedContainersStatuses.add(convertFromProtoFormat(c));
}
}
@Override
public synchronized void setCompletedContainersStatuses(
final List<ContainerStatus> containers) {
if (containers == null)
return;
initLocalFinishedContainerList();
completedContainersStatuses.addAll(containers);
}
private synchronized NodeReportPBImpl convertFromProtoFormat(
NodeReportProto p) {
return new NodeReportPBImpl(p);
}
private synchronized NodeReportProto convertToProtoFormat(NodeReport t) {
return ((NodeReportPBImpl)t).getProto();
}
private synchronized ContainerPBImpl convertFromProtoFormat(
ContainerProto p) {
return new ContainerPBImpl(p);
}
private synchronized ContainerProto convertToProtoFormat(Container t) {
return ((ContainerPBImpl)t).getProto();
}
private synchronized ContainerStatusPBImpl convertFromProtoFormat(
ContainerStatusProto p) {
return new ContainerStatusPBImpl(p);
}
private synchronized ContainerStatusProto convertToProtoFormat(ContainerStatus t) {
return ((ContainerStatusPBImpl)t).getProto();
}
private synchronized ResourcePBImpl convertFromProtoFormat(ResourceProto p) {
return new ResourcePBImpl(p);
}
private synchronized ResourceProto convertToProtoFormat(Resource r) {
return ((ResourcePBImpl) r).getProto();
}
}

View File

@ -207,16 +207,6 @@ message ResourceRequestProto {
optional int32 num_containers = 4; optional int32 num_containers = 4;
} }
message AMResponseProto {
optional bool reboot = 1;
optional int32 response_id = 2;
repeated ContainerProto allocated_containers = 3;
repeated ContainerStatusProto completed_container_statuses = 4;
optional ResourceProto limit = 5;
repeated NodeReportProto updated_nodes = 6;
}
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
////// From client_RM_Protocol ///////////////////////////////////////// ////// From client_RM_Protocol /////////////////////////////////////////
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////

View File

@ -59,8 +59,13 @@ message AllocateRequestProto {
} }
message AllocateResponseProto { message AllocateResponseProto {
optional AMResponseProto AM_response = 1; optional bool reboot = 1;
optional int32 num_cluster_nodes = 2; optional int32 response_id = 2;
repeated ContainerProto allocated_containers = 3;
repeated ContainerStatusProto completed_container_statuses = 4;
optional ResourceProto limit = 5;
repeated NodeReportProto updated_nodes = 6;
optional int32 num_cluster_nodes = 7;
} }

View File

@ -53,7 +53,6 @@
import org.apache.hadoop.yarn.api.protocolrecords.RegisterApplicationMasterResponse; import org.apache.hadoop.yarn.api.protocolrecords.RegisterApplicationMasterResponse;
import org.apache.hadoop.yarn.api.protocolrecords.StartContainerRequest; import org.apache.hadoop.yarn.api.protocolrecords.StartContainerRequest;
import org.apache.hadoop.yarn.api.records.AMResponse;
import org.apache.hadoop.yarn.api.records.ApplicationAttemptId; import org.apache.hadoop.yarn.api.records.ApplicationAttemptId;
import org.apache.hadoop.yarn.api.records.Container; import org.apache.hadoop.yarn.api.records.Container;
import org.apache.hadoop.yarn.api.records.ContainerId; import org.apache.hadoop.yarn.api.records.ContainerId;
@ -510,10 +509,11 @@ public boolean run() throws YarnRemoteException {
// Send the request to RM // Send the request to RM
LOG.info("Asking RM for containers" + ", askCount=" + askCount); LOG.info("Asking RM for containers" + ", askCount=" + askCount);
AMResponse amResp = sendContainerAskToRM(); AllocateResponse allocResp = sendContainerAskToRM();
// Retrieve list of allocated containers from the response // Retrieve list of allocated containers from the response
List<Container> allocatedContainers = amResp.getAllocatedContainers(); List<Container> allocatedContainers =
allocResp.getAllocatedContainers();
LOG.info("Got response from RM for container ask, allocatedCnt=" LOG.info("Got response from RM for container ask, allocatedCnt="
+ allocatedContainers.size()); + allocatedContainers.size());
numAllocatedContainers.addAndGet(allocatedContainers.size()); numAllocatedContainers.addAndGet(allocatedContainers.size());
@ -542,12 +542,12 @@ public boolean run() throws YarnRemoteException {
// Check what the current available resources in the cluster are // Check what the current available resources in the cluster are
// TODO should we do anything if the available resources are not enough? // TODO should we do anything if the available resources are not enough?
Resource availableResources = amResp.getAvailableResources(); Resource availableResources = allocResp.getAvailableResources();
LOG.info("Current available resources in the cluster " LOG.info("Current available resources in the cluster "
+ availableResources); + availableResources);
// Check the completed containers // Check the completed containers
List<ContainerStatus> completedContainers = amResp List<ContainerStatus> completedContainers = allocResp
.getCompletedContainersStatuses(); .getCompletedContainersStatuses();
LOG.info("Got response from RM for container ask, completedCnt=" LOG.info("Got response from RM for container ask, completedCnt="
+ completedContainers.size()); + completedContainers.size());
@ -819,14 +819,13 @@ private ContainerRequest setupContainerAskForRM(int numContainers) {
* @return Response from RM to AM with allocated containers * @return Response from RM to AM with allocated containers
* @throws YarnRemoteException * @throws YarnRemoteException
*/ */
private AMResponse sendContainerAskToRM() throws YarnRemoteException { private AllocateResponse sendContainerAskToRM() throws YarnRemoteException {
float progressIndicator = (float) numCompletedContainers.get() float progressIndicator = (float) numCompletedContainers.get()
/ numTotalContainers; / numTotalContainers;
LOG.info("Sending request to RM for containers" + ", progress=" LOG.info("Sending request to RM for containers" + ", progress="
+ progressIndicator); + progressIndicator);
AllocateResponse resp = resourceManager.allocate(progressIndicator); return resourceManager.allocate(progressIndicator);
return resp.getAMResponse();
} }
} }

View File

@ -45,7 +45,6 @@
import org.apache.hadoop.yarn.api.protocolrecords.FinishApplicationMasterRequest; import org.apache.hadoop.yarn.api.protocolrecords.FinishApplicationMasterRequest;
import org.apache.hadoop.yarn.api.protocolrecords.RegisterApplicationMasterRequest; import org.apache.hadoop.yarn.api.protocolrecords.RegisterApplicationMasterRequest;
import org.apache.hadoop.yarn.api.protocolrecords.RegisterApplicationMasterResponse; import org.apache.hadoop.yarn.api.protocolrecords.RegisterApplicationMasterResponse;
import org.apache.hadoop.yarn.api.records.AMResponse;
import org.apache.hadoop.yarn.api.records.ApplicationAttemptId; import org.apache.hadoop.yarn.api.records.ApplicationAttemptId;
import org.apache.hadoop.yarn.api.records.ContainerId; import org.apache.hadoop.yarn.api.records.ContainerId;
import org.apache.hadoop.yarn.api.records.FinalApplicationStatus; import org.apache.hadoop.yarn.api.records.FinalApplicationStatus;
@ -194,13 +193,12 @@ public AllocateResponse allocate(float progressIndicator)
} }
allocateResponse = rmClient.allocate(allocateRequest); allocateResponse = rmClient.allocate(allocateRequest);
AMResponse response = allocateResponse.getAMResponse();
synchronized (this) { synchronized (this) {
// update these on successful RPC // update these on successful RPC
clusterNodeCount = allocateResponse.getNumClusterNodes(); clusterNodeCount = allocateResponse.getNumClusterNodes();
lastResponseId = response.getResponseId(); lastResponseId = allocateResponse.getResponseId();
clusterAvailableResources = response.getAvailableResources(); clusterAvailableResources = allocateResponse.getAvailableResources();
} }
} finally { } finally {
// TODO how to differentiate remote yarn exception vs error in rpc // TODO how to differentiate remote yarn exception vs error in rpc

View File

@ -36,7 +36,6 @@
import org.apache.hadoop.yarn.api.protocolrecords.AllocateResponse; import org.apache.hadoop.yarn.api.protocolrecords.AllocateResponse;
import org.apache.hadoop.yarn.api.protocolrecords.GetNewApplicationResponse; import org.apache.hadoop.yarn.api.protocolrecords.GetNewApplicationResponse;
import org.apache.hadoop.yarn.api.protocolrecords.SubmitApplicationRequest; import org.apache.hadoop.yarn.api.protocolrecords.SubmitApplicationRequest;
import org.apache.hadoop.yarn.api.records.AMResponse;
import org.apache.hadoop.yarn.api.records.ApplicationAttemptId; import org.apache.hadoop.yarn.api.records.ApplicationAttemptId;
import org.apache.hadoop.yarn.api.records.ApplicationId; import org.apache.hadoop.yarn.api.records.ApplicationId;
import org.apache.hadoop.yarn.api.records.ApplicationReport; import org.apache.hadoop.yarn.api.records.ApplicationReport;
@ -202,9 +201,8 @@ private void testAllocation(final AMRMClientImpl amClient)
assertTrue(amClient.release.size() == 0); assertTrue(amClient.release.size() == 0);
assertTrue(nodeCount == amClient.getClusterNodeCount()); assertTrue(nodeCount == amClient.getClusterNodeCount());
AMResponse amResponse = allocResponse.getAMResponse(); allocatedContainerCount += allocResponse.getAllocatedContainers().size();
allocatedContainerCount += amResponse.getAllocatedContainers().size(); for(Container container : allocResponse.getAllocatedContainers()) {
for(Container container : amResponse.getAllocatedContainers()) {
ContainerId rejectContainerId = container.getId(); ContainerId rejectContainerId = container.getId();
releases.add(rejectContainerId); releases.add(rejectContainerId);
amClient.releaseAssignedContainer(rejectContainerId); amClient.releaseAssignedContainer(rejectContainerId);
@ -264,11 +262,11 @@ public AllocateResponse answer(InvocationOnMock invocation)
while(!releases.isEmpty() || iterationsLeft-- > 0) { while(!releases.isEmpty() || iterationsLeft-- > 0) {
// inform RM of rejection // inform RM of rejection
AllocateResponse allocResponse = amClient.allocate(0.1f); AllocateResponse allocResponse = amClient.allocate(0.1f);
AMResponse amResponse = allocResponse.getAMResponse();
// RM did not send new containers because AM does not need any // RM did not send new containers because AM does not need any
assertTrue(amResponse.getAllocatedContainers().size() == 0); assertTrue(allocResponse.getAllocatedContainers().size() == 0);
if(amResponse.getCompletedContainersStatuses().size() > 0) { if(allocResponse.getCompletedContainersStatuses().size() > 0) {
for(ContainerStatus cStatus : amResponse.getCompletedContainersStatuses()) { for(ContainerStatus cStatus :allocResponse
.getCompletedContainersStatuses()) {
if(releases.contains(cStatus.getContainerId())) { if(releases.contains(cStatus.getContainerId())) {
assertTrue(cStatus.getState() == ContainerState.COMPLETE); assertTrue(cStatus.getState() == ContainerState.COMPLETE);
assertTrue(cStatus.getExitStatus() == -100); assertTrue(cStatus.getExitStatus() == -100);

View File

@ -23,9 +23,9 @@
import org.apache.hadoop.yarn.factories.RecordFactory; import org.apache.hadoop.yarn.factories.RecordFactory;
import org.apache.hadoop.yarn.factories.impl.pb.RecordFactoryPBImpl; import org.apache.hadoop.yarn.factories.impl.pb.RecordFactoryPBImpl;
import org.apache.hadoop.yarn.api.protocolrecords.AllocateRequest; import org.apache.hadoop.yarn.api.protocolrecords.AllocateRequest;
import org.apache.hadoop.yarn.api.protocolrecords.AllocateResponse;
import org.apache.hadoop.yarn.api.protocolrecords.impl.pb.AllocateRequestPBImpl; import org.apache.hadoop.yarn.api.protocolrecords.impl.pb.AllocateRequestPBImpl;
import org.apache.hadoop.yarn.api.records.AMResponse; import org.apache.hadoop.yarn.api.protocolrecords.impl.pb.AllocateResponsePBImpl;
import org.apache.hadoop.yarn.api.records.impl.pb.AMResponsePBImpl;
import org.junit.Test; import org.junit.Test;
public class TestRecordFactory { public class TestRecordFactory {
@ -35,15 +35,17 @@ public void testPbRecordFactory() {
RecordFactory pbRecordFactory = RecordFactoryPBImpl.get(); RecordFactory pbRecordFactory = RecordFactoryPBImpl.get();
try { try {
AMResponse response = pbRecordFactory.newRecordInstance(AMResponse.class); AllocateResponse response =
Assert.assertEquals(AMResponsePBImpl.class, response.getClass()); pbRecordFactory.newRecordInstance(AllocateResponse.class);
Assert.assertEquals(AllocateResponsePBImpl.class, response.getClass());
} catch (YarnException e) { } catch (YarnException e) {
e.printStackTrace(); e.printStackTrace();
Assert.fail("Failed to crete record"); Assert.fail("Failed to crete record");
} }
try { try {
AllocateRequest response = pbRecordFactory.newRecordInstance(AllocateRequest.class); AllocateRequest response =
pbRecordFactory.newRecordInstance(AllocateRequest.class);
Assert.assertEquals(AllocateRequestPBImpl.class, response.getClass()); Assert.assertEquals(AllocateRequestPBImpl.class, response.getClass());
} catch (YarnException e) { } catch (YarnException e) {
e.printStackTrace(); e.printStackTrace();

View File

@ -41,7 +41,6 @@
import org.apache.hadoop.yarn.api.protocolrecords.FinishApplicationMasterResponse; import org.apache.hadoop.yarn.api.protocolrecords.FinishApplicationMasterResponse;
import org.apache.hadoop.yarn.api.protocolrecords.RegisterApplicationMasterRequest; import org.apache.hadoop.yarn.api.protocolrecords.RegisterApplicationMasterRequest;
import org.apache.hadoop.yarn.api.protocolrecords.RegisterApplicationMasterResponse; import org.apache.hadoop.yarn.api.protocolrecords.RegisterApplicationMasterResponse;
import org.apache.hadoop.yarn.api.records.AMResponse;
import org.apache.hadoop.yarn.api.records.ApplicationAttemptId; import org.apache.hadoop.yarn.api.records.ApplicationAttemptId;
import org.apache.hadoop.yarn.api.records.ApplicationId; import org.apache.hadoop.yarn.api.records.ApplicationId;
import org.apache.hadoop.yarn.api.records.ContainerId; import org.apache.hadoop.yarn.api.records.ContainerId;
@ -78,10 +77,12 @@ public class ApplicationMasterService extends AbstractService implements
private YarnScheduler rScheduler; private YarnScheduler rScheduler;
private InetSocketAddress bindAddress; private InetSocketAddress bindAddress;
private Server server; private Server server;
private final RecordFactory recordFactory = RecordFactoryProvider.getRecordFactory(null); private final RecordFactory recordFactory =
private final ConcurrentMap<ApplicationAttemptId, AMResponse> responseMap = RecordFactoryProvider.getRecordFactory(null);
new ConcurrentHashMap<ApplicationAttemptId, AMResponse>(); private final ConcurrentMap<ApplicationAttemptId, AllocateResponse> responseMap =
private final AMResponse reboot = recordFactory.newRecordInstance(AMResponse.class); new ConcurrentHashMap<ApplicationAttemptId, AllocateResponse>();
private final AllocateResponse reboot =
recordFactory.newRecordInstance(AllocateResponse.class);
private final RMContext rmContext; private final RMContext rmContext;
public ApplicationMasterService(RMContext rmContext, YarnScheduler scheduler) { public ApplicationMasterService(RMContext rmContext, YarnScheduler scheduler) {
@ -166,7 +167,7 @@ public RegisterApplicationMasterResponse registerApplicationMaster(
authorizeRequest(applicationAttemptId); authorizeRequest(applicationAttemptId);
ApplicationId appID = applicationAttemptId.getApplicationId(); ApplicationId appID = applicationAttemptId.getApplicationId();
AMResponse lastResponse = responseMap.get(applicationAttemptId); AllocateResponse lastResponse = responseMap.get(applicationAttemptId);
if (lastResponse == null) { if (lastResponse == null) {
String message = "Application doesn't exist in cache " String message = "Application doesn't exist in cache "
+ applicationAttemptId; + applicationAttemptId;
@ -214,7 +215,7 @@ public FinishApplicationMasterResponse finishApplicationMaster(
.getApplicationAttemptId(); .getApplicationAttemptId();
authorizeRequest(applicationAttemptId); authorizeRequest(applicationAttemptId);
AMResponse lastResponse = responseMap.get(applicationAttemptId); AllocateResponse lastResponse = responseMap.get(applicationAttemptId);
if (lastResponse == null) { if (lastResponse == null) {
String message = "Application doesn't exist in cache " String message = "Application doesn't exist in cache "
+ applicationAttemptId; + applicationAttemptId;
@ -248,25 +249,20 @@ public AllocateResponse allocate(AllocateRequest request)
this.amLivelinessMonitor.receivedPing(appAttemptId); this.amLivelinessMonitor.receivedPing(appAttemptId);
/* check if its in cache */ /* check if its in cache */
AllocateResponse allocateResponse = recordFactory AllocateResponse lastResponse = responseMap.get(appAttemptId);
.newRecordInstance(AllocateResponse.class);
AMResponse lastResponse = responseMap.get(appAttemptId);
if (lastResponse == null) { if (lastResponse == null) {
LOG.error("AppAttemptId doesnt exist in cache " + appAttemptId); LOG.error("AppAttemptId doesnt exist in cache " + appAttemptId);
allocateResponse.setAMResponse(reboot); return reboot;
return allocateResponse;
} }
if ((request.getResponseId() + 1) == lastResponse.getResponseId()) { if ((request.getResponseId() + 1) == lastResponse.getResponseId()) {
/* old heartbeat */ /* old heartbeat */
allocateResponse.setAMResponse(lastResponse); return lastResponse;
return allocateResponse;
} else if (request.getResponseId() + 1 < lastResponse.getResponseId()) { } else if (request.getResponseId() + 1 < lastResponse.getResponseId()) {
LOG.error("Invalid responseid from appAttemptId " + appAttemptId); LOG.error("Invalid responseid from appAttemptId " + appAttemptId);
// Oh damn! Sending reboot isn't enough. RM state is corrupted. TODO: // Oh damn! Sending reboot isn't enough. RM state is corrupted. TODO:
// Reboot is not useful since after AM reboots, it will send register and // Reboot is not useful since after AM reboots, it will send register and
// get an exception. Might as well throw an exception here. // get an exception. Might as well throw an exception here.
allocateResponse.setAMResponse(reboot); return reboot;
return allocateResponse;
} }
// Allow only one thread in AM to do heartbeat at a time. // Allow only one thread in AM to do heartbeat at a time.
@ -288,7 +284,8 @@ public AllocateResponse allocate(AllocateRequest request)
appAttemptId.getApplicationId()); appAttemptId.getApplicationId());
RMAppAttempt appAttempt = app.getRMAppAttempt(appAttemptId); RMAppAttempt appAttempt = app.getRMAppAttempt(appAttemptId);
AMResponse response = recordFactory.newRecordInstance(AMResponse.class); AllocateResponse allocateResponse =
recordFactory.newRecordInstance(AllocateResponse.class);
// update the response with the deltas of node status changes // update the response with the deltas of node status changes
List<RMNode> updatedNodes = new ArrayList<RMNode>(); List<RMNode> updatedNodes = new ArrayList<RMNode>();
@ -311,34 +308,34 @@ public AllocateResponse allocate(AllocateRequest request)
updatedNodeReports.add(report); updatedNodeReports.add(report);
} }
response.setUpdatedNodes(updatedNodeReports); allocateResponse.setUpdatedNodes(updatedNodeReports);
} }
response.setAllocatedContainers(allocation.getContainers()); allocateResponse.setAllocatedContainers(allocation.getContainers());
response.setCompletedContainersStatuses(appAttempt allocateResponse.setCompletedContainersStatuses(appAttempt
.pullJustFinishedContainers()); .pullJustFinishedContainers());
response.setResponseId(lastResponse.getResponseId() + 1); allocateResponse.setResponseId(lastResponse.getResponseId() + 1);
response.setAvailableResources(allocation.getResourceLimit()); allocateResponse.setAvailableResources(allocation.getResourceLimit());
AMResponse oldResponse = responseMap.put(appAttemptId, response); AllocateResponse oldResponse =
responseMap.put(appAttemptId, allocateResponse);
if (oldResponse == null) { if (oldResponse == null) {
// appAttempt got unregistered, remove it back out // appAttempt got unregistered, remove it back out
responseMap.remove(appAttemptId); responseMap.remove(appAttemptId);
String message = "App Attempt removed from the cache during allocate" String message = "App Attempt removed from the cache during allocate"
+ appAttemptId; + appAttemptId;
LOG.error(message); LOG.error(message);
allocateResponse.setAMResponse(reboot); return reboot;
return allocateResponse;
} }
allocateResponse.setAMResponse(response);
allocateResponse.setNumClusterNodes(this.rScheduler.getNumClusterNodes()); allocateResponse.setNumClusterNodes(this.rScheduler.getNumClusterNodes());
return allocateResponse; return allocateResponse;
} }
} }
public void registerAppAttempt(ApplicationAttemptId attemptId) { public void registerAppAttempt(ApplicationAttemptId attemptId) {
AMResponse response = recordFactory.newRecordInstance(AMResponse.class); AllocateResponse response =
recordFactory.newRecordInstance(AllocateResponse.class);
response.setResponseId(0); response.setResponseId(0);
LOG.info("Registering " + attemptId); LOG.info("Registering " + attemptId);
responseMap.put(attemptId, response); responseMap.put(attemptId, response);

View File

@ -28,8 +28,6 @@
import org.apache.hadoop.yarn.api.protocolrecords.AllocateResponse; import org.apache.hadoop.yarn.api.protocolrecords.AllocateResponse;
import org.apache.hadoop.yarn.api.protocolrecords.FinishApplicationMasterRequest; import org.apache.hadoop.yarn.api.protocolrecords.FinishApplicationMasterRequest;
import org.apache.hadoop.yarn.api.protocolrecords.RegisterApplicationMasterRequest; import org.apache.hadoop.yarn.api.protocolrecords.RegisterApplicationMasterRequest;
import org.apache.hadoop.yarn.api.protocolrecords.RegisterApplicationMasterResponse;
import org.apache.hadoop.yarn.api.records.AMResponse;
import org.apache.hadoop.yarn.api.records.ApplicationAttemptId; import org.apache.hadoop.yarn.api.records.ApplicationAttemptId;
import org.apache.hadoop.yarn.api.records.FinalApplicationStatus; import org.apache.hadoop.yarn.api.records.FinalApplicationStatus;
import org.apache.hadoop.yarn.api.records.ContainerId; import org.apache.hadoop.yarn.api.records.ContainerId;
@ -96,14 +94,14 @@ public void addRequests(String[] hosts, int memory, int priority,
requests.addAll(createReq(hosts, memory, priority, containers)); requests.addAll(createReq(hosts, memory, priority, containers));
} }
public AMResponse schedule() throws Exception { public AllocateResponse schedule() throws Exception {
AMResponse response = allocate(requests, releases); AllocateResponse response = allocate(requests, releases);
requests.clear(); requests.clear();
releases.clear(); releases.clear();
return response; return response;
} }
public AMResponse allocate( public AllocateResponse allocate(
String host, int memory, int numContainers, String host, int memory, int numContainers,
List<ContainerId> releases) throws Exception { List<ContainerId> releases) throws Exception {
List<ResourceRequest> reqs = createReq(new String[]{host}, memory, 1, numContainers); List<ResourceRequest> reqs = createReq(new String[]{host}, memory, 1, numContainers);
@ -143,13 +141,12 @@ public ResourceRequest createResourceReq(String resource, int memory, int priori
return req; return req;
} }
public AMResponse allocate( public AllocateResponse allocate(
List<ResourceRequest> resourceRequest, List<ContainerId> releases) List<ResourceRequest> resourceRequest, List<ContainerId> releases)
throws Exception { throws Exception {
AllocateRequest req = BuilderUtils.newAllocateRequest(attemptId, AllocateRequest req = BuilderUtils.newAllocateRequest(attemptId,
++responseId, 0F, resourceRequest, releases); ++responseId, 0F, resourceRequest, releases);
AllocateResponse resp = amRMProtocol.allocate(req); return amRMProtocol.allocate(req);
return resp.getAMResponse();
} }
public void unregisterAppAttempt() throws Exception { public void unregisterAppAttempt() throws Exception {

View File

@ -26,7 +26,7 @@
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.yarn.api.records.AMResponse; import org.apache.hadoop.yarn.api.protocolrecords.AllocateResponse;
import org.apache.hadoop.yarn.api.records.ApplicationAttemptId; import org.apache.hadoop.yarn.api.records.ApplicationAttemptId;
import org.apache.hadoop.yarn.api.records.ApplicationId; import org.apache.hadoop.yarn.api.records.ApplicationId;
import org.apache.hadoop.yarn.api.records.Container; import org.apache.hadoop.yarn.api.records.Container;
@ -99,32 +99,32 @@ public void test() throws Exception {
// add request for containers // add request for containers
am1.addRequests(new String[] { "h1", "h2" }, GB, 1, 1); am1.addRequests(new String[] { "h1", "h2" }, GB, 1, 1);
AMResponse am1Response = am1.schedule(); // send the request AllocateResponse alloc1Response = am1.schedule(); // send the request
// add request for containers // add request for containers
am2.addRequests(new String[] { "h1", "h2" }, 3 * GB, 0, 1); am2.addRequests(new String[] { "h1", "h2" }, 3 * GB, 0, 1);
AMResponse am2Response = am2.schedule(); // send the request AllocateResponse alloc2Response = am2.schedule(); // send the request
// kick the scheduler, 1 GB and 3 GB given to AM1 and AM2, remaining 0 // kick the scheduler, 1 GB and 3 GB given to AM1 and AM2, remaining 0
nm1.nodeHeartbeat(true); nm1.nodeHeartbeat(true);
while (am1Response.getAllocatedContainers().size() < 1) { while (alloc1Response.getAllocatedContainers().size() < 1) {
LOG.info("Waiting for containers to be created for app 1..."); LOG.info("Waiting for containers to be created for app 1...");
Thread.sleep(1000); Thread.sleep(1000);
am1Response = am1.schedule(); alloc1Response = am1.schedule();
} }
while (am2Response.getAllocatedContainers().size() < 1) { while (alloc2Response.getAllocatedContainers().size() < 1) {
LOG.info("Waiting for containers to be created for app 2..."); LOG.info("Waiting for containers to be created for app 2...");
Thread.sleep(1000); Thread.sleep(1000);
am2Response = am2.schedule(); alloc2Response = am2.schedule();
} }
// kick the scheduler, nothing given remaining 2 GB. // kick the scheduler, nothing given remaining 2 GB.
nm2.nodeHeartbeat(true); nm2.nodeHeartbeat(true);
List<Container> allocated1 = am1Response.getAllocatedContainers(); List<Container> allocated1 = alloc1Response.getAllocatedContainers();
Assert.assertEquals(1, allocated1.size()); Assert.assertEquals(1, allocated1.size());
Assert.assertEquals(1 * GB, allocated1.get(0).getResource().getMemory()); Assert.assertEquals(1 * GB, allocated1.get(0).getResource().getMemory());
Assert.assertEquals(nm1.getNodeId(), allocated1.get(0).getNodeId()); Assert.assertEquals(nm1.getNodeId(), allocated1.get(0).getNodeId());
List<Container> allocated2 = am2Response.getAllocatedContainers(); List<Container> allocated2 = alloc2Response.getAllocatedContainers();
Assert.assertEquals(1, allocated2.size()); Assert.assertEquals(1, allocated2.size());
Assert.assertEquals(3 * GB, allocated2.get(0).getResource().getMemory()); Assert.assertEquals(3 * GB, allocated2.get(0).getResource().getMemory());
Assert.assertEquals(nm1.getNodeId(), allocated2.get(0).getNodeId()); Assert.assertEquals(nm1.getNodeId(), allocated2.get(0).getNodeId());

View File

@ -23,7 +23,7 @@
import java.util.Map; import java.util.Map;
import org.apache.hadoop.util.ExitUtil; import org.apache.hadoop.util.ExitUtil;
import org.apache.hadoop.yarn.api.records.AMResponse; import org.apache.hadoop.yarn.api.protocolrecords.AllocateResponse;
import org.apache.hadoop.yarn.api.records.ApplicationAttemptId; import org.apache.hadoop.yarn.api.records.ApplicationAttemptId;
import org.apache.hadoop.yarn.api.records.ApplicationId; import org.apache.hadoop.yarn.api.records.ApplicationId;
import org.apache.hadoop.yarn.api.records.Container; import org.apache.hadoop.yarn.api.records.Container;
@ -213,9 +213,10 @@ public void testRMRestart() throws Exception {
// verify old AM is not accepted // verify old AM is not accepted
// change running AM to talk to new RM // change running AM to talk to new RM
am1.setAMRMProtocol(rm2.getApplicationMasterService()); am1.setAMRMProtocol(rm2.getApplicationMasterService());
AMResponse amResponse = am1.allocate(new ArrayList<ResourceRequest>(), AllocateResponse allocResponse = am1.allocate(
new ArrayList<ResourceRequest>(),
new ArrayList<ContainerId>()); new ArrayList<ContainerId>());
Assert.assertTrue(amResponse.getReboot()); Assert.assertTrue(allocResponse.getReboot());
// NM should be rebooted on heartbeat, even first heartbeat for nm2 // NM should be rebooted on heartbeat, even first heartbeat for nm2
HeartbeatResponse hbResponse = nm1.nodeHeartbeat(true); HeartbeatResponse hbResponse = nm1.nodeHeartbeat(true);

View File

@ -21,7 +21,7 @@
import junit.framework.Assert; import junit.framework.Assert;
import org.apache.hadoop.yarn.api.protocolrecords.AllocateRequest; import org.apache.hadoop.yarn.api.protocolrecords.AllocateRequest;
import org.apache.hadoop.yarn.api.records.AMResponse; import org.apache.hadoop.yarn.api.protocolrecords.AllocateResponse;
import org.apache.hadoop.yarn.api.records.NodeReport; import org.apache.hadoop.yarn.api.records.NodeReport;
import org.apache.hadoop.yarn.api.records.NodeState; import org.apache.hadoop.yarn.api.records.NodeState;
import org.apache.hadoop.yarn.event.Dispatcher; import org.apache.hadoop.yarn.event.Dispatcher;
@ -109,7 +109,7 @@ public void testAMRMUnusableNodes() throws Exception {
// allocate request returns no updated node // allocate request returns no updated node
AllocateRequest allocateRequest1 = BuilderUtils.newAllocateRequest(attempt1 AllocateRequest allocateRequest1 = BuilderUtils.newAllocateRequest(attempt1
.getAppAttemptId(), 0, 0F, null, null); .getAppAttemptId(), 0, 0F, null, null);
AMResponse response1 = amService.allocate(allocateRequest1).getAMResponse(); AllocateResponse response1 = amService.allocate(allocateRequest1);
List<NodeReport> updatedNodes = response1.getUpdatedNodes(); List<NodeReport> updatedNodes = response1.getUpdatedNodes();
Assert.assertEquals(0, updatedNodes.size()); Assert.assertEquals(0, updatedNodes.size());
@ -118,7 +118,7 @@ public void testAMRMUnusableNodes() throws Exception {
// allocate request returns updated node // allocate request returns updated node
allocateRequest1 = BuilderUtils.newAllocateRequest(attempt1 allocateRequest1 = BuilderUtils.newAllocateRequest(attempt1
.getAppAttemptId(), response1.getResponseId(), 0F, null, null); .getAppAttemptId(), response1.getResponseId(), 0F, null, null);
response1 = amService.allocate(allocateRequest1).getAMResponse(); response1 = amService.allocate(allocateRequest1);
updatedNodes = response1.getUpdatedNodes(); updatedNodes = response1.getUpdatedNodes();
Assert.assertEquals(1, updatedNodes.size()); Assert.assertEquals(1, updatedNodes.size());
NodeReport nr = updatedNodes.iterator().next(); NodeReport nr = updatedNodes.iterator().next();
@ -126,7 +126,7 @@ public void testAMRMUnusableNodes() throws Exception {
Assert.assertEquals(NodeState.UNHEALTHY, nr.getNodeState()); Assert.assertEquals(NodeState.UNHEALTHY, nr.getNodeState());
// resending the allocate request returns the same result // resending the allocate request returns the same result
response1 = amService.allocate(allocateRequest1).getAMResponse(); response1 = amService.allocate(allocateRequest1);
updatedNodes = response1.getUpdatedNodes(); updatedNodes = response1.getUpdatedNodes();
Assert.assertEquals(1, updatedNodes.size()); Assert.assertEquals(1, updatedNodes.size());
nr = updatedNodes.iterator().next(); nr = updatedNodes.iterator().next();
@ -138,7 +138,7 @@ public void testAMRMUnusableNodes() throws Exception {
// subsequent allocate request returns delta // subsequent allocate request returns delta
allocateRequest1 = BuilderUtils.newAllocateRequest(attempt1 allocateRequest1 = BuilderUtils.newAllocateRequest(attempt1
.getAppAttemptId(), response1.getResponseId(), 0F, null, null); .getAppAttemptId(), response1.getResponseId(), 0F, null, null);
response1 = amService.allocate(allocateRequest1).getAMResponse(); response1 = amService.allocate(allocateRequest1);
updatedNodes = response1.getUpdatedNodes(); updatedNodes = response1.getUpdatedNodes();
Assert.assertEquals(1, updatedNodes.size()); Assert.assertEquals(1, updatedNodes.size());
nr = updatedNodes.iterator().next(); nr = updatedNodes.iterator().next();
@ -158,7 +158,7 @@ public void testAMRMUnusableNodes() throws Exception {
// allocate request returns no updated node // allocate request returns no updated node
AllocateRequest allocateRequest2 = BuilderUtils.newAllocateRequest(attempt2 AllocateRequest allocateRequest2 = BuilderUtils.newAllocateRequest(attempt2
.getAppAttemptId(), 0, 0F, null, null); .getAppAttemptId(), 0, 0F, null, null);
AMResponse response2 = amService.allocate(allocateRequest2).getAMResponse(); AllocateResponse response2 = amService.allocate(allocateRequest2);
updatedNodes = response2.getUpdatedNodes(); updatedNodes = response2.getUpdatedNodes();
Assert.assertEquals(0, updatedNodes.size()); Assert.assertEquals(0, updatedNodes.size());
@ -167,7 +167,7 @@ public void testAMRMUnusableNodes() throws Exception {
// both AM's should get delta updated nodes // both AM's should get delta updated nodes
allocateRequest1 = BuilderUtils.newAllocateRequest(attempt1 allocateRequest1 = BuilderUtils.newAllocateRequest(attempt1
.getAppAttemptId(), response1.getResponseId(), 0F, null, null); .getAppAttemptId(), response1.getResponseId(), 0F, null, null);
response1 = amService.allocate(allocateRequest1).getAMResponse(); response1 = amService.allocate(allocateRequest1);
updatedNodes = response1.getUpdatedNodes(); updatedNodes = response1.getUpdatedNodes();
Assert.assertEquals(1, updatedNodes.size()); Assert.assertEquals(1, updatedNodes.size());
nr = updatedNodes.iterator().next(); nr = updatedNodes.iterator().next();
@ -176,7 +176,7 @@ public void testAMRMUnusableNodes() throws Exception {
allocateRequest2 = BuilderUtils.newAllocateRequest(attempt2 allocateRequest2 = BuilderUtils.newAllocateRequest(attempt2
.getAppAttemptId(), response2.getResponseId(), 0F, null, null); .getAppAttemptId(), response2.getResponseId(), 0F, null, null);
response2 = amService.allocate(allocateRequest2).getAMResponse(); response2 = amService.allocate(allocateRequest2);
updatedNodes = response2.getUpdatedNodes(); updatedNodes = response2.getUpdatedNodes();
Assert.assertEquals(1, updatedNodes.size()); Assert.assertEquals(1, updatedNodes.size());
nr = updatedNodes.iterator().next(); nr = updatedNodes.iterator().next();
@ -186,7 +186,7 @@ public void testAMRMUnusableNodes() throws Exception {
// subsequent allocate calls should return no updated nodes // subsequent allocate calls should return no updated nodes
allocateRequest2 = BuilderUtils.newAllocateRequest(attempt2 allocateRequest2 = BuilderUtils.newAllocateRequest(attempt2
.getAppAttemptId(), response2.getResponseId(), 0F, null, null); .getAppAttemptId(), response2.getResponseId(), 0F, null, null);
response2 = amService.allocate(allocateRequest2).getAMResponse(); response2 = amService.allocate(allocateRequest2);
updatedNodes = response2.getUpdatedNodes(); updatedNodes = response2.getUpdatedNodes();
Assert.assertEquals(0, updatedNodes.size()); Assert.assertEquals(0, updatedNodes.size());

View File

@ -21,7 +21,7 @@
import junit.framework.Assert; import junit.framework.Assert;
import org.apache.hadoop.yarn.api.protocolrecords.AllocateRequest; import org.apache.hadoop.yarn.api.protocolrecords.AllocateRequest;
import org.apache.hadoop.yarn.api.records.AMResponse; import org.apache.hadoop.yarn.api.protocolrecords.AllocateResponse;
import org.apache.hadoop.yarn.factories.RecordFactory; import org.apache.hadoop.yarn.factories.RecordFactory;
import org.apache.hadoop.yarn.factory.providers.RecordFactoryProvider; import org.apache.hadoop.yarn.factory.providers.RecordFactoryProvider;
import org.apache.hadoop.yarn.server.resourcemanager.ApplicationMasterService; import org.apache.hadoop.yarn.server.resourcemanager.ApplicationMasterService;
@ -81,22 +81,22 @@ public void testARRMResponseId() throws Exception {
AllocateRequest allocateRequest = BuilderUtils.newAllocateRequest(attempt AllocateRequest allocateRequest = BuilderUtils.newAllocateRequest(attempt
.getAppAttemptId(), 0, 0F, null, null); .getAppAttemptId(), 0, 0F, null, null);
AMResponse response = amService.allocate(allocateRequest).getAMResponse(); AllocateResponse response = amService.allocate(allocateRequest);
Assert.assertEquals(1, response.getResponseId()); Assert.assertEquals(1, response.getResponseId());
Assert.assertFalse(response.getReboot()); Assert.assertFalse(response.getReboot());
allocateRequest = BuilderUtils.newAllocateRequest(attempt allocateRequest = BuilderUtils.newAllocateRequest(attempt
.getAppAttemptId(), response.getResponseId(), 0F, null, null); .getAppAttemptId(), response.getResponseId(), 0F, null, null);
response = amService.allocate(allocateRequest).getAMResponse(); response = amService.allocate(allocateRequest);
Assert.assertEquals(2, response.getResponseId()); Assert.assertEquals(2, response.getResponseId());
/* try resending */ /* try resending */
response = amService.allocate(allocateRequest).getAMResponse(); response = amService.allocate(allocateRequest);
Assert.assertEquals(2, response.getResponseId()); Assert.assertEquals(2, response.getResponseId());
/** try sending old request again **/ /** try sending old request again **/
allocateRequest = BuilderUtils.newAllocateRequest(attempt allocateRequest = BuilderUtils.newAllocateRequest(attempt
.getAppAttemptId(), 0, 0F, null, null); .getAppAttemptId(), 0, 0F, null, null);
response = amService.allocate(allocateRequest).getAMResponse(); response = amService.allocate(allocateRequest);
Assert.assertTrue(response.getReboot()); Assert.assertTrue(response.getReboot());
} }
} }

View File

@ -201,8 +201,7 @@ public void testMasterKeyRollOver() throws Exception {
AllocateRequest allocateRequest = AllocateRequest allocateRequest =
Records.newRecord(AllocateRequest.class); Records.newRecord(AllocateRequest.class);
allocateRequest.setApplicationAttemptId(applicationAttemptId); allocateRequest.setApplicationAttemptId(applicationAttemptId);
Assert.assertFalse(rmClient.allocate(allocateRequest).getAMResponse() Assert.assertFalse(rmClient.allocate(allocateRequest).getReboot());
.getReboot());
// Simulate a master-key-roll-over // Simulate a master-key-roll-over
ApplicationTokenSecretManager appTokenSecretManager = ApplicationTokenSecretManager appTokenSecretManager =
@ -218,8 +217,7 @@ public void testMasterKeyRollOver() throws Exception {
rmClient = createRMClient(rm, conf, rpc, currentUser); rmClient = createRMClient(rm, conf, rpc, currentUser);
allocateRequest = Records.newRecord(AllocateRequest.class); allocateRequest = Records.newRecord(AllocateRequest.class);
allocateRequest.setApplicationAttemptId(applicationAttemptId); allocateRequest.setApplicationAttemptId(applicationAttemptId);
Assert.assertFalse(rmClient.allocate(allocateRequest).getAMResponse() Assert.assertFalse(rmClient.allocate(allocateRequest).getReboot());
.getReboot());
} finally { } finally {
rm.stop(); rm.stop();
if (rmClient != null) { if (rmClient != null) {

View File

@ -487,7 +487,7 @@ private Container requestAndGetContainer(AMRMProtocol scheduler,
BuilderUtils.newApplicationAttemptId(appID, 1), 0, 0F, ask, BuilderUtils.newApplicationAttemptId(appID, 1), 0, 0F, ask,
new ArrayList<ContainerId>()); new ArrayList<ContainerId>());
List<Container> allocatedContainers = scheduler.allocate(allocateRequest) List<Container> allocatedContainers = scheduler.allocate(allocateRequest)
.getAMResponse().getAllocatedContainers(); .getAllocatedContainers();
// Modify ask to request no more. // Modify ask to request no more.
allocateRequest.clearAsks(); allocateRequest.clearAsks();
@ -499,7 +499,7 @@ private Container requestAndGetContainer(AMRMProtocol scheduler,
Thread.sleep(1000); Thread.sleep(1000);
allocateRequest.setResponseId(allocateRequest.getResponseId() + 1); allocateRequest.setResponseId(allocateRequest.getResponseId() + 1);
allocatedContainers = scheduler.allocate(allocateRequest) allocatedContainers = scheduler.allocate(allocateRequest)
.getAMResponse().getAllocatedContainers(); .getAllocatedContainers();
} }
Assert.assertNotNull("Container is not allocted!", allocatedContainers); Assert.assertNotNull("Container is not allocted!", allocatedContainers);

View File

@ -493,7 +493,7 @@ Hadoop MapReduce Next Generation - Writing YARN Applications
+---+ +---+
* The AllocateResponse sent back from the ResourceManager provides the * The AllocateResponse sent back from the ResourceManager provides the
following information via the AMResponse object: following information:
* Reboot flag: For scenarios when the ApplicationMaster may get out of sync * Reboot flag: For scenarios when the ApplicationMaster may get out of sync
with the ResourceManager. with the ResourceManager.
@ -513,6 +513,8 @@ Hadoop MapReduce Next Generation - Writing YARN Applications
status of the completed container and take appropriate actions such as status of the completed container and take appropriate actions such as
re-trying a particular sub-task in case of a failure. re-trying a particular sub-task in case of a failure.
* Number of cluster nodes: The number of hosts available on the cluster.
[] []
One thing to note is that containers will not be immediately allocated to One thing to note is that containers will not be immediately allocated to
@ -525,13 +527,11 @@ Hadoop MapReduce Next Generation - Writing YARN Applications
containers. containers.
+---+ +---+
// Get AMResponse from AllocateResponse
AMResponse amResp = allocateResponse.getAMResponse();
// Retrieve list of allocated containers from the response // Retrieve list of allocated containers from the response
// and on each allocated container, lets assume we are launching // and on each allocated container, lets assume we are launching
// the same job. // the same job.
List<Container> allocatedContainers = amResp.getAllocatedContainers(); List<Container> allocatedContainers = allocateResponse.getAllocatedContainers();
for (Container allocatedContainer : allocatedContainers) { for (Container allocatedContainer : allocatedContainers) {
LOG.info("Launching shell command on a new container." LOG.info("Launching shell command on a new container."
+ ", containerId=" + allocatedContainer.getId() + ", containerId=" + allocatedContainer.getId()
@ -553,7 +553,7 @@ Hadoop MapReduce Next Generation - Writing YARN Applications
} }
// Check what the current available resources in the cluster are // Check what the current available resources in the cluster are
Resource availableResources = amResp.getAvailableResources(); Resource availableResources = allocateResponse.getAvailableResources();
// Based on this information, an ApplicationMaster can make appropriate // Based on this information, an ApplicationMaster can make appropriate
// decisions // decisions
@ -561,7 +561,7 @@ Hadoop MapReduce Next Generation - Writing YARN Applications
// Let's assume we are keeping a count of total completed containers, // Let's assume we are keeping a count of total completed containers,
// containers that failed and ones that completed successfully. // containers that failed and ones that completed successfully.
List<ContainerStatus> completedContainers = List<ContainerStatus> completedContainers =
amResp.getCompletedContainersStatuses(); allocateResponse.getCompletedContainersStatuses();
for (ContainerStatus containerStatus : completedContainers) { for (ContainerStatus containerStatus : completedContainers) {
LOG.info("Got container status for containerID= " LOG.info("Got container status for containerID= "
+ containerStatus.getContainerId() + containerStatus.getContainerId()
@ -611,7 +611,7 @@ Hadoop MapReduce Next Generation - Writing YARN Applications
+---+ +---+
//Assuming an allocated Container obtained from AMResponse //Assuming an allocated Container obtained from AllocateResponse
Container container; Container container;
// Connect to ContainerManager on the allocated container // Connect to ContainerManager on the allocated container
String cmIpPortStr = container.getNodeId().getHost() + ":" String cmIpPortStr = container.getNodeId().getHost() + ":"