YARN-3717. Expose app/am/queue's node-label-expression to RM web UI / CLI / REST-API. (Naganarasimha G R via wangda)

This commit is contained in:
Wangda Tan 2015-09-15 11:40:50 -07:00
parent b2017d9b03
commit ae5308fe1d
29 changed files with 412 additions and 63 deletions

View File

@ -436,6 +436,9 @@ Release 2.8.0 - UNRELEASED
YARN-2005. Blacklisting support for scheduling AMs. (Anubhav Dhoot via kasha)
YARN-3717. Expose app/am/queue's node-label-expression to RM web UI /
CLI / REST-API. (Naganarasimha G R via wangda)
OPTIMIZATIONS
YARN-3339. TestDockerContainerExecutor should pull a single image and not

View File

@ -91,8 +91,9 @@ public static ApplicationReport newInstance(ApplicationId applicationId,
YarnApplicationState state, String diagnostics, String url,
long startTime, long finishTime, FinalApplicationStatus finalStatus,
ApplicationResourceUsageReport appResources, String origTrackingUrl,
float progress, String applicationType, Token amRmToken,
Set<String> tags, boolean unmanagedApplication, Priority priority) {
float progress, String applicationType, Token amRmToken, Set<String> tags,
boolean unmanagedApplication, Priority priority,
String appNodeLabelExpression, String amNodeLabelExpression) {
ApplicationReport report =
newInstance(applicationId, applicationAttemptId, user, queue, name,
host, rpcPort, clientToAMToken, state, diagnostics, url, startTime,
@ -101,6 +102,8 @@ public static ApplicationReport newInstance(ApplicationId applicationId,
report.setApplicationTags(tags);
report.setUnmanagedApp(unmanagedApplication);
report.setPriority(priority);
report.setAppNodeLabelExpression(appNodeLabelExpression);
report.setAmNodeLabelExpression(amNodeLabelExpression);
return report;
}
@ -422,4 +425,26 @@ public abstract void setLogAggregationStatus(
@Private
@Unstable
public abstract void setPriority(Priority priority);
/**
* Get the default Node Label expression for all the application's containers
*
* @return Application's NodeLabelExpression
*/
@Unstable
public abstract String getAppNodeLabelExpression();
@Unstable
public abstract void setAppNodeLabelExpression(String appNodeLabelExpression);
/**
* Get the default Node Label expression for all the application's containers
*
* @return Application's NodeLabelExpression
*/
@Unstable
public abstract String getAmNodeLabelExpression();
@Unstable
public abstract void setAmNodeLabelExpression(String amNodeLabelExpression);
}

View File

@ -27,6 +27,22 @@
@Public
@Unstable
public abstract class NodeLabel implements Comparable<NodeLabel> {
/**
* Default node label partition.
*/
@Private
@Unstable
public static final String DEFAULT_NODE_LABEL_PARTITION =
"<DEFAULT_PARTITION>";
/**
* Node Label expression not set .
*/
@Private
@Unstable
public static final String NODE_LABEL_EXPRESSION_NOT_SET = "<Not set>";
/**
* By default, node label is exclusive or not
*/

View File

@ -197,6 +197,8 @@ message ApplicationReportProto {
optional LogAggregationStatusProto log_aggregation_status = 21;
optional bool unmanaged_application = 22 [default = false];
optional PriorityProto priority = 23;
optional string appNodeLabelExpression = 24;
optional string amNodeLabelExpression = 25;
}
enum LogAggregationStatusProto {

View File

@ -554,7 +554,11 @@ private int printApplicationReport(String applicationId)
appReportStr.print("\tDiagnostics : ");
appReportStr.println(appReport.getDiagnostics());
appReportStr.print("\tUnmanaged Application : ");
appReportStr.print(appReport.isUnmanagedApp());
appReportStr.println(appReport.isUnmanagedApp());
appReportStr.print("\tApplication Node Label Expression : ");
appReportStr.println(appReport.getAppNodeLabelExpression());
appReportStr.print("\tAM container Node Label Expression : ");
appReportStr.print(appReport.getAmNodeLabelExpression());
} else {
appReportStr.print("Application with id '" + applicationId
+ "' doesn't exist in RM.");

View File

@ -32,6 +32,7 @@
import org.apache.hadoop.classification.InterfaceAudience.Private;
import org.apache.hadoop.classification.InterfaceStability.Unstable;
import org.apache.hadoop.util.ToolRunner;
import org.apache.hadoop.yarn.api.records.NodeLabel;
import org.apache.hadoop.yarn.api.records.QueueInfo;
import org.apache.hadoop.yarn.exceptions.YarnException;
@ -135,11 +136,11 @@ private void printQueueInfo(PrintWriter writer, QueueInfo queueInfo) {
writer.print("\tMaximum Capacity : ");
writer.println(df.format(queueInfo.getMaximumCapacity() * 100) + "%");
writer.print("\tDefault Node Label expression : ");
if (null != queueInfo.getDefaultNodeLabelExpression()) {
writer.println(queueInfo.getDefaultNodeLabelExpression());
} else {
writer.println();
}
String nodeLabelExpression = queueInfo.getDefaultNodeLabelExpression();
nodeLabelExpression =
(nodeLabelExpression == null || nodeLabelExpression.trim().isEmpty())
? NodeLabel.DEFAULT_NODE_LABEL_PARTITION : nodeLabelExpression;
writer.println(nodeLabelExpression);
Set<String> nodeLabels = queueInfo.getAccessibleNodeLabels();
StringBuilder labelList = new StringBuilder();

View File

@ -54,6 +54,7 @@
import org.apache.hadoop.yarn.api.records.FinalApplicationStatus;
import org.apache.hadoop.yarn.api.records.LogAggregationStatus;
import org.apache.hadoop.yarn.api.records.NodeId;
import org.apache.hadoop.yarn.api.records.NodeLabel;
import org.apache.hadoop.yarn.api.records.NodeReport;
import org.apache.hadoop.yarn.api.records.NodeState;
import org.apache.hadoop.yarn.api.records.Priority;
@ -104,7 +105,7 @@ public void testGetApplicationReport() throws Exception {
"user", "queue", "appname", "host", 124, null,
YarnApplicationState.FINISHED, "diagnostics", "url", 0, 0,
FinalApplicationStatus.SUCCEEDED, usageReport, "N/A", 0.53789f, "YARN",
null, null, false, Priority.newInstance(0));
null, null, false, Priority.newInstance(0), "high-mem", "high-mem");
newApplicationReport.setLogAggregationStatus(LogAggregationStatus.SUCCEEDED);
newApplicationReport.setPriority(Priority.newInstance(0));
when(client.getApplicationReport(any(ApplicationId.class))).thenReturn(
@ -134,6 +135,8 @@ public void testGetApplicationReport() throws Exception {
pw.println("\tLog Aggregation Status : SUCCEEDED");
pw.println("\tDiagnostics : diagnostics");
pw.println("\tUnmanaged Application : false");
pw.println("\tApplication Node Label Expression : high-mem");
pw.println("\tAM container Node Label Expression : high-mem");
pw.close();
String appReportStr = baos.toString("UTF-8");
Assert.assertEquals(appReportStr, sysOutStream.toString());
@ -1311,7 +1314,8 @@ public void testGetQueueInfoWithEmptyNodeLabel() throws Exception {
pw.println("\tCapacity : " + "40.0%");
pw.println("\tCurrent Capacity : " + "50.0%");
pw.println("\tMaximum Capacity : " + "80.0%");
pw.println("\tDefault Node Label expression : ");
pw.println("\tDefault Node Label expression : "
+ NodeLabel.DEFAULT_NODE_LABEL_PARTITION);
pw.println("\tAccessible Node Labels : ");
pw.close();
String queueInfoStr = baos.toString("UTF-8");

View File

@ -630,4 +630,42 @@ public void setPriority(Priority priority) {
builder.clearPriority();
this.priority = priority;
}
@Override
public String getAppNodeLabelExpression() {
ApplicationReportProtoOrBuilder p = viaProto ? proto : builder;
if (!p.hasAppNodeLabelExpression()) {
return null;
}
return p.getAppNodeLabelExpression();
}
@Override
public void setAppNodeLabelExpression(String appNodeLabelExpression) {
maybeInitBuilder();
if (appNodeLabelExpression == null) {
builder.clearAppNodeLabelExpression();
return;
}
builder.setAppNodeLabelExpression((appNodeLabelExpression));
}
@Override
public String getAmNodeLabelExpression() {
ApplicationReportProtoOrBuilder p = viaProto ? proto : builder;
if (!p.hasAmNodeLabelExpression()) {
return null;
}
return p.getAmNodeLabelExpression();
}
@Override
public void setAmNodeLabelExpression(String amNodeLabelExpression) {
maybeInitBuilder();
if (amNodeLabelExpression == null) {
builder.clearAmNodeLabelExpression();
return;
}
builder.setAmNodeLabelExpression((amNodeLabelExpression));
}
}

View File

@ -60,7 +60,7 @@ protected static ApplicationReport createApplicationReport(
"appname", "host", 124, null, YarnApplicationState.FINISHED,
"diagnostics", "url", 0, 0, FinalApplicationStatus.SUCCEEDED, null,
"N/A", 0.53789f, YarnConfiguration.DEFAULT_APPLICATION_TYPE, null,
null, false, Priority.newInstance(0));
null, false, Priority.newInstance(0),"","");
return appReport;
}

View File

@ -260,6 +260,8 @@ private static ApplicationReportExt convertToApplicationReport(
Set<String> appTags = null;
Map<ApplicationAccessType, String> appViewACLs =
new HashMap<ApplicationAccessType, String>();
String appNodeLabelExpression = null;
String amNodeLabelExpression = null;
Map<String, Object> entityInfo = entity.getOtherInfo();
if (entityInfo != null) {
if (entityInfo.containsKey(ApplicationMetricsConstants.USER_ENTITY_INFO)) {
@ -280,8 +282,8 @@ private static ApplicationReportExt convertToApplicationReport(
latestApplicationAttemptId, user, queue, name, null, -1, null,
state, diagnosticsInfo, null, createdTime, finishedTime,
finalStatus, null, null, progress, type, null, appTags,
unmanagedApplication, Priority.newInstance(applicationPriority)),
appViewACLs);
unmanagedApplication, Priority.newInstance(applicationPriority),
appNodeLabelExpression, amNodeLabelExpression), appViewACLs);
}
if (entityInfo.containsKey(ApplicationMetricsConstants.QUEUE_ENTITY_INFO)) {
queue =
@ -298,6 +300,11 @@ private static ApplicationReportExt convertToApplicationReport(
entityInfo.get(ApplicationMetricsConstants.TYPE_ENTITY_INFO)
.toString();
}
if (entityInfo.containsKey(ApplicationMetricsConstants.TYPE_ENTITY_INFO)) {
type =
entityInfo.get(ApplicationMetricsConstants.TYPE_ENTITY_INFO)
.toString();
}
if (entityInfo
.containsKey(ApplicationMetricsConstants.UNMANAGED_APPLICATION_ENTITY_INFO)) {
unmanagedApplication =
@ -310,6 +317,18 @@ private static ApplicationReportExt convertToApplicationReport(
applicationPriority = Integer.parseInt(entityInfo.get(
ApplicationMetricsConstants.APPLICATION_PRIORITY_INFO).toString());
}
if (entityInfo
.containsKey(ApplicationMetricsConstants.APP_NODE_LABEL_EXPRESSION)) {
appNodeLabelExpression = entityInfo
.get(ApplicationMetricsConstants.APP_NODE_LABEL_EXPRESSION).toString();
}
if (entityInfo
.containsKey(ApplicationMetricsConstants.AM_NODE_LABEL_EXPRESSION)) {
amNodeLabelExpression =
entityInfo.get(ApplicationMetricsConstants.AM_NODE_LABEL_EXPRESSION)
.toString();
}
if (entityInfo.containsKey(ApplicationMetricsConstants.APP_CPU_METRICS)) {
long vcoreSeconds=Long.parseLong(entityInfo.get(
ApplicationMetricsConstants.APP_CPU_METRICS).toString());
@ -381,9 +400,9 @@ private static ApplicationReportExt convertToApplicationReport(
ConverterUtils.toApplicationId(entity.getEntityId()),
latestApplicationAttemptId, user, queue, name, null, -1, null, state,
diagnosticsInfo, null, createdTime, finishedTime, finalStatus,
appResources, null, progress, type, null, appTags,
unmanagedApplication, Priority.newInstance(applicationPriority)),
appViewACLs);
appResources, null, progress, type, null, appTags, unmanagedApplication,
Priority.newInstance(applicationPriority), appNodeLabelExpression,
amNodeLabelExpression), appViewACLs);
}
private static ApplicationAttemptReport convertToApplicationAttemptReport(

View File

@ -80,4 +80,10 @@ public class ApplicationMetricsConstants {
public static final String APPLICATION_PRIORITY_INFO =
"YARN_APPLICATION_PRIORITY";
public static final String APP_NODE_LABEL_EXPRESSION =
"YARN_APP_NODE_LABEL_EXPRESSION";
public static final String AM_NODE_LABEL_EXPRESSION =
"YARN_AM_NODE_LABEL_EXPRESSION";
}

View File

@ -208,6 +208,12 @@ public ApplicationReport run() throws Exception {
overviewTable._("Diagnostics:",
app.getDiagnosticsInfo() == null ? "" : app.getDiagnosticsInfo());
overviewTable._("Unmanaged Application:", app.isUnmanagedApp());
overviewTable._("Application Node Label expression:",
app.getAppNodeLabelExpression() == null ? "<Not set>"
: app.getAppNodeLabelExpression());
overviewTable._("AM container Node Label expression:",
app.getAmNodeLabelExpression() == null ? "<Not set>"
: app.getAmNodeLabelExpression());
Collection<ApplicationAttemptReport> attempts;
try {

View File

@ -62,6 +62,8 @@ public class AppInfo {
private int allocatedCpuVcores;
private int allocatedMemoryMB;
protected boolean unmanagedApplication;
private String appNodeLabelExpression;
private String amNodeLabelExpression;
public AppInfo() {
// JAXB needs this
@ -106,6 +108,8 @@ public AppInfo(ApplicationReport app) {
this.applicationTags = CSV_JOINER.join(app.getApplicationTags());
}
unmanagedApplication = app.isUnmanagedApp();
appNodeLabelExpression = app.getAppNodeLabelExpression();
amNodeLabelExpression = app.getAmNodeLabelExpression();
}
public String getAppId() {
@ -203,4 +207,12 @@ public boolean isUnmanagedApp() {
public int getPriority() {
return priority;
}
public String getAppNodeLabelExpression() {
return appNodeLabelExpression;
}
public String getAmNodeLabelExpression() {
return amNodeLabelExpression;
}
}

View File

@ -35,6 +35,8 @@ public class ApplicationCreatedEvent extends
private Set<String> appTags;
private boolean unmanagedApplication;
private Priority applicationPriority;
private String appNodeLabelsExpression;
private String amNodeLabelsExpression;
public ApplicationCreatedEvent(ApplicationId appId,
String name,
@ -45,7 +47,9 @@ public ApplicationCreatedEvent(ApplicationId appId,
long createdTime,
Set<String> appTags,
boolean unmanagedApplication,
Priority applicationPriority) {
Priority applicationPriority,
String appNodeLabelsExpression,
String amNodeLabelsExpression) {
super(SystemMetricsEventType.APP_CREATED, createdTime);
this.appId = appId;
this.name = name;
@ -56,6 +60,8 @@ public ApplicationCreatedEvent(ApplicationId appId,
this.appTags = appTags;
this.unmanagedApplication = unmanagedApplication;
this.applicationPriority = applicationPriority;
this.appNodeLabelsExpression = appNodeLabelsExpression;
this.amNodeLabelsExpression = amNodeLabelsExpression;
}
@Override
@ -98,4 +104,12 @@ public boolean isUnmanagedApp() {
public Priority getApplicationPriority() {
return applicationPriority;
}
public String getAppNodeLabelsExpression() {
return appNodeLabelsExpression;
}
public String getAmNodeLabelsExpression() {
return amNodeLabelsExpression;
}
}

View File

@ -31,6 +31,7 @@
import org.apache.hadoop.service.CompositeService;
import org.apache.hadoop.yarn.api.records.ApplicationAttemptId;
import org.apache.hadoop.yarn.api.records.ApplicationId;
import org.apache.hadoop.yarn.api.records.ApplicationSubmissionContext;
import org.apache.hadoop.yarn.api.records.ContainerId;
import org.apache.hadoop.yarn.api.records.timeline.TimelineEntity;
import org.apache.hadoop.yarn.api.records.timeline.TimelineEvent;
@ -45,6 +46,7 @@
import org.apache.hadoop.yarn.server.metrics.ContainerMetricsConstants;
import org.apache.hadoop.yarn.server.resourcemanager.RMServerUtils;
import org.apache.hadoop.yarn.server.resourcemanager.rmapp.RMApp;
import org.apache.hadoop.yarn.server.resourcemanager.rmapp.RMAppImpl;
import org.apache.hadoop.yarn.server.resourcemanager.rmapp.RMAppMetrics;
import org.apache.hadoop.yarn.server.resourcemanager.rmapp.RMAppState;
import org.apache.hadoop.yarn.server.resourcemanager.rmapp.attempt.RMAppAttempt;
@ -98,6 +100,8 @@ protected void serviceInit(Configuration conf) throws Exception {
@SuppressWarnings("unchecked")
public void appCreated(RMApp app, long createdTime) {
if (publishSystemMetrics) {
ApplicationSubmissionContext appSubmissionContext =
app.getApplicationSubmissionContext();
dispatcher.getEventHandler().handle(
new ApplicationCreatedEvent(
app.getApplicationId(),
@ -107,8 +111,10 @@ public void appCreated(RMApp app, long createdTime) {
app.getQueue(),
app.getSubmitTime(),
createdTime, app.getApplicationTags(),
app.getApplicationSubmissionContext().getUnmanagedAM(),
app.getApplicationSubmissionContext().getPriority()));
appSubmissionContext.getUnmanagedAM(),
appSubmissionContext.getPriority(),
app.getAppNodeLabelExpression(),
app.getAmNodeLabelExpression()));
}
}
@ -260,6 +266,10 @@ private void publishApplicationCreatedEvent(ApplicationCreatedEvent event) {
event.isUnmanagedApp());
entityInfo.put(ApplicationMetricsConstants.APPLICATION_PRIORITY_INFO,
event.getApplicationPriority().getPriority());
entityInfo.put(ApplicationMetricsConstants.APP_NODE_LABEL_EXPRESSION,
event.getAppNodeLabelsExpression());
entityInfo.put(ApplicationMetricsConstants.AM_NODE_LABEL_EXPRESSION,
event.getAmNodeLabelsExpression());
entity.setOtherInfo(entityInfo);
TimelineEvent tEvent = new TimelineEvent();
tEvent.setEventType(

View File

@ -248,4 +248,10 @@ ApplicationReport createAndGetApplicationReport(String clientUserName,
Map<NodeId, LogAggregationReport> getLogAggregationReportsForApp();
LogAggregationStatus getLogAggregationStatusForAppReport();
/**
* Return the node label expression of the AM container.
*/
String getAmNodeLabelExpression();
String getAppNodeLabelExpression();
}

View File

@ -56,6 +56,7 @@
import org.apache.hadoop.yarn.api.records.FinalApplicationStatus;
import org.apache.hadoop.yarn.api.records.LogAggregationStatus;
import org.apache.hadoop.yarn.api.records.NodeId;
import org.apache.hadoop.yarn.api.records.NodeLabel;
import org.apache.hadoop.yarn.api.records.NodeState;
import org.apache.hadoop.yarn.api.records.ReservationId;
import org.apache.hadoop.yarn.api.records.Resource;
@ -683,6 +684,8 @@ public ApplicationReport createAndGetApplicationReport(String clientUserName,
this.submissionContext.getPriority());
report.setLogAggregationStatus(logAggregationStatus);
report.setUnmanagedApp(submissionContext.getUnmanagedAM());
report.setAppNodeLabelExpression(getAppNodeLabelExpression());
report.setAmNodeLabelExpression(getAmNodeLabelExpression());
return report;
} finally {
this.readLock.unlock();
@ -1700,4 +1703,28 @@ public String getLogAggregationFailureMessagesForNM(NodeId nodeId) {
this.readLock.unlock();
}
}
@Override
public String getAppNodeLabelExpression() {
String appNodeLabelExpression =
getApplicationSubmissionContext().getNodeLabelExpression();
appNodeLabelExpression = (appNodeLabelExpression == null)
? NodeLabel.NODE_LABEL_EXPRESSION_NOT_SET : appNodeLabelExpression;
appNodeLabelExpression = (appNodeLabelExpression.trim().isEmpty())
? NodeLabel.DEFAULT_NODE_LABEL_PARTITION : appNodeLabelExpression;
return appNodeLabelExpression;
}
@Override
public String getAmNodeLabelExpression() {
String amNodeLabelExpression = null;
if (!getApplicationSubmissionContext().getUnmanagedAM()) {
amNodeLabelExpression = getAMResourceRequest().getNodeLabelExpression();
amNodeLabelExpression = (amNodeLabelExpression == null)
? NodeLabel.NODE_LABEL_EXPRESSION_NOT_SET : amNodeLabelExpression;
amNodeLabelExpression = (amNodeLabelExpression.trim().isEmpty())
? NodeLabel.DEFAULT_NODE_LABEL_PARTITION : amNodeLabelExpression;
}
return amNodeLabelExpression;
}
}

View File

@ -27,6 +27,7 @@
import org.apache.hadoop.security.UserGroupInformation;
import org.apache.hadoop.util.StringUtils;
import org.apache.hadoop.yarn.api.records.NodeLabel;
import org.apache.hadoop.yarn.nodelabels.RMNodeLabel;
import org.apache.hadoop.yarn.server.resourcemanager.ResourceManager;
import org.apache.hadoop.yarn.server.resourcemanager.nodelabels.RMNodeLabelsManager;
@ -91,7 +92,8 @@ protected void render(Block html) {
}
private void renderLeafQueueInfoWithPartition(Block html) {
nodeLabel = nodeLabel.length() == 0 ? "<DEFAULT_PARTITION>" : nodeLabel;
nodeLabel = nodeLabel.length() == 0
? NodeLabel.DEFAULT_NODE_LABEL_PARTITION : nodeLabel;
// first display the queue's label specific details :
ResponseInfo ri =
info("\'" + lqinfo.getQueuePath().substring(5)
@ -152,7 +154,11 @@ private void renderCommonLeafQueueInfo(ResponseInfo ri) {
"%.1f", lqinfo.getUserLimitFactor())).
_("Accessible Node Labels:", StringUtils.join(",", lqinfo.getNodeLabels())).
_("Ordering Policy: ", lqinfo.getOrderingPolicyInfo()).
_("Preemption:", lqinfo.getPreemptionDisabled() ? "disabled" : "enabled");
_("Preemption:", lqinfo.getPreemptionDisabled() ? "disabled" : "enabled").
_("Default Node Label Expression:",
lqinfo.getDefaultNodeLabelExpression() == null
? NodeLabel.DEFAULT_NODE_LABEL_PARTITION
: lqinfo.getDefaultNodeLabelExpression());
}
}
@ -363,9 +369,8 @@ public void render(Block html) {
csqinfo.csinfo = sinfo;
csqinfo.qinfo = null;
csqinfo.label = label.getLabelName();
String nodeLabel =
csqinfo.label.length() == 0 ? "<DEFAULT_PARTITION>"
: csqinfo.label;
String nodeLabel = csqinfo.label.length() == 0
? NodeLabel.DEFAULT_NODE_LABEL_PARTITION : csqinfo.label;
QueueCapacities queueCapacities = root.getQueueCapacities();
used = queueCapacities.getUsedCapacity(label.getLabelName());
String partitionUiTag =

View File

@ -20,6 +20,7 @@
import static org.apache.hadoop.yarn.webapp.view.JQueryUI.DATATABLES_ID;
import org.apache.hadoop.yarn.api.records.NodeLabel;
import org.apache.hadoop.yarn.nodelabels.RMNodeLabel;
import org.apache.hadoop.yarn.server.resourcemanager.ResourceManager;
import org.apache.hadoop.yarn.server.resourcemanager.nodelabels.RMNodeLabelsManager;
@ -58,9 +59,8 @@ protected void render(Block html) {
RMNodeLabelsManager nlm = rm.getRMContext().getNodeLabelManager();
for (RMNodeLabel info : nlm.pullRMNodeLabelsInfo()) {
TR<TBODY<TABLE<Hamlet>>> row =
tbody.tr().td(
info.getLabelName().isEmpty() ? "<DEFAULT_PARTITION>" : info
.getLabelName());
tbody.tr().td(info.getLabelName().isEmpty()
? NodeLabel.DEFAULT_NODE_LABEL_PARTITION : info.getLabelName());
String type =
(info.getIsExclusive()) ? "Exclusive Partition"
: "Non Exclusive Partition";

View File

@ -26,6 +26,7 @@
import org.apache.hadoop.yarn.api.records.ApplicationId;
import org.apache.hadoop.yarn.api.records.ApplicationResourceUsageReport;
import org.apache.hadoop.yarn.api.records.ApplicationSubmissionContext;
import org.apache.hadoop.yarn.api.records.Container;
import org.apache.hadoop.yarn.api.records.FinalApplicationStatus;
import org.apache.hadoop.yarn.api.records.LogAggregationStatus;
@ -98,6 +99,8 @@ public class AppInfo {
protected LogAggregationStatus logAggregationStatus;
protected boolean unmanagedApplication;
protected String appNodeLabelExpression;
protected String amNodeLabelExpression;
public AppInfo() {
} // JAXB needs this
@ -132,8 +135,10 @@ public AppInfo(ResourceManager rm, RMApp app, Boolean hasAccess,
this.name = app.getName().toString();
this.queue = app.getQueue().toString();
this.priority = 0;
if (app.getApplicationSubmissionContext().getPriority() != null) {
this.priority = app.getApplicationSubmissionContext().getPriority()
ApplicationSubmissionContext appSubmissionContext =
app.getApplicationSubmissionContext();
if (appSubmissionContext.getPriority() != null) {
this.priority = appSubmissionContext.getPriority()
.getPriority();
}
this.progress = app.getProgress() * 100;
@ -191,7 +196,11 @@ public AppInfo(ResourceManager rm, RMApp app, Boolean hasAccess,
memorySeconds = appMetrics.getMemorySeconds();
vcoreSeconds = appMetrics.getVcoreSeconds();
unmanagedApplication =
app.getApplicationSubmissionContext().getUnmanagedAM();
appSubmissionContext.getUnmanagedAM();
appNodeLabelExpression =
app.getApplicationSubmissionContext().getNodeLabelExpression();
amNodeLabelExpression = (unmanagedApplication) ? null
: app.getAMResourceRequest().getNodeLabelExpression();
}
}
@ -338,4 +347,12 @@ public boolean isUnmanagedApp() {
public int getPriority() {
return this.priority;
}
public String getAppNodeLabelExpression() {
return this.appNodeLabelExpression;
}
public String getAmNodeLabelExpression() {
return this.amNodeLabelExpression;
}
}

View File

@ -40,6 +40,7 @@ public class CapacitySchedulerLeafQueueInfo extends CapacitySchedulerQueueInfo {
protected ResourceInfo usedAMResource;
protected ResourceInfo userAMResourceLimit;
protected boolean preemptionDisabled;
protected String defaultNodeLabelExpression;
@XmlTransient
protected String orderingPolicyInfo;
@ -62,6 +63,7 @@ public class CapacitySchedulerLeafQueueInfo extends CapacitySchedulerQueueInfo {
userAMResourceLimit = new ResourceInfo(q.getUserAMResourceLimit());
preemptionDisabled = q.getPreemptionDisabled();
orderingPolicyInfo = q.getOrderingPolicy().getInfo();
defaultNodeLabelExpression = q.getDefaultNodeLabelExpression();
}
public int getNumActiveApplications() {
@ -116,4 +118,8 @@ public boolean getPreemptionDisabled() {
public String getOrderingPolicyInfo() {
return orderingPolicyInfo;
}
public String getDefaultNodeLabelExpression() {
return defaultNodeLabelExpression;
}
}

View File

@ -300,6 +300,33 @@ public void testGetApplicationReport() throws Exception {
report.getApplicationResourceUsageReport();
Assert.assertEquals(10, usageReport.getMemorySeconds());
Assert.assertEquals(3, usageReport.getVcoreSeconds());
Assert.assertEquals("<Not set>", report.getAmNodeLabelExpression());
Assert.assertEquals("<Not set>", report.getAppNodeLabelExpression());
// if application has am node label set to blank
ApplicationId appId2 = getApplicationId(2);
when(mockAclsManager.checkAccess(UserGroupInformation.getCurrentUser(),
ApplicationAccessType.VIEW_APP, null, appId2)).thenReturn(true);
request.setApplicationId(appId2);
response = rmService.getApplicationReport(request);
report = response.getApplicationReport();
Assert.assertEquals(NodeLabel.DEFAULT_NODE_LABEL_PARTITION,
report.getAmNodeLabelExpression());
Assert.assertEquals(NodeLabel.NODE_LABEL_EXPRESSION_NOT_SET,
report.getAppNodeLabelExpression());
// if application has am node label set to blank
ApplicationId appId3 = getApplicationId(3);
when(mockAclsManager.checkAccess(UserGroupInformation.getCurrentUser(),
ApplicationAccessType.VIEW_APP, null, appId3)).thenReturn(true);
request.setApplicationId(appId3);
response = rmService.getApplicationReport(request);
report = response.getApplicationReport();
Assert.assertEquals("high-mem", report.getAmNodeLabelExpression());
Assert.assertEquals("high-mem", report.getAppNodeLabelExpression());
// if application id is null
GetApplicationReportRequest invalidRequest = recordFactory
@ -951,11 +978,11 @@ private ConcurrentHashMap<ApplicationId, RMApp> getRMApps(
ApplicationId applicationId3 = getApplicationId(3);
YarnConfiguration config = new YarnConfiguration();
apps.put(applicationId1, getRMApp(rmContext, yarnScheduler, applicationId1,
config, "testqueue", 10, 3));
config, "testqueue", 10, 3,null,null));
apps.put(applicationId2, getRMApp(rmContext, yarnScheduler, applicationId2,
config, "a", 20, 2));
config, "a", 20, 2,null,""));
apps.put(applicationId3, getRMApp(rmContext, yarnScheduler, applicationId3,
config, "testqueue", 40, 5));
config, "testqueue", 40, 5,"high-mem","high-mem"));
return apps;
}
@ -978,10 +1005,11 @@ private static ApplicationAttemptId getApplicationAttemptId(int id) {
private RMAppImpl getRMApp(RMContext rmContext, YarnScheduler yarnScheduler,
ApplicationId applicationId3, YarnConfiguration config, String queueName,
final long memorySeconds, final long vcoreSeconds) {
final long memorySeconds, final long vcoreSeconds,
String appNodeLabelExpression, String amNodeLabelExpression) {
ApplicationSubmissionContext asContext = mock(ApplicationSubmissionContext.class);
when(asContext.getMaxAppAttempts()).thenReturn(1);
when(asContext.getNodeLabelExpression()).thenReturn(appNodeLabelExpression);
RMAppImpl app =
spy(new RMAppImpl(applicationId3, rmContext, config, null, null,
queueName, asContext, yarnScheduler, null,
@ -1002,7 +1030,7 @@ public ApplicationReport createAndGetApplicationReport(
return report;
}
});
app.getAMResourceRequest().setNodeLabelExpression(amNodeLabelExpression);
ApplicationAttemptId attemptId = ApplicationAttemptId.newInstance(
ApplicationId.newInstance(123456, 1), 1);
RMAppAttemptImpl rmAppAttemptImpl = spy(new RMAppAttemptImpl(attemptId,

View File

@ -202,6 +202,16 @@ public Map<NodeId, LogAggregationReport> getLogAggregationReportsForApp() {
public LogAggregationStatus getLogAggregationStatusForAppReport() {
throw new UnsupportedOperationException("Not supported yet.");
}
@Override
public String getAmNodeLabelExpression() {
throw new UnsupportedOperationException("Not supported yet.");
}
@Override
public String getAppNodeLabelExpression() {
throw new UnsupportedOperationException("Not supported yet.");
}
}
public static RMApp newApplication(int i) {

View File

@ -37,6 +37,7 @@
import org.apache.hadoop.yarn.api.records.NodeId;
import org.apache.hadoop.yarn.api.records.Priority;
import org.apache.hadoop.yarn.api.records.Resource;
import org.apache.hadoop.yarn.api.records.ResourceRequest;
import org.apache.hadoop.yarn.api.records.YarnApplicationAttemptState;
import org.apache.hadoop.yarn.api.records.YarnApplicationState;
import org.apache.hadoop.yarn.api.records.timeline.TimelineEntity;
@ -47,6 +48,7 @@
import org.apache.hadoop.yarn.server.metrics.ApplicationMetricsConstants;
import org.apache.hadoop.yarn.server.metrics.ContainerMetricsConstants;
import org.apache.hadoop.yarn.server.resourcemanager.rmapp.RMApp;
import org.apache.hadoop.yarn.server.resourcemanager.rmapp.RMAppImpl;
import org.apache.hadoop.yarn.server.resourcemanager.rmapp.RMAppMetrics;
import org.apache.hadoop.yarn.server.resourcemanager.rmapp.RMAppState;
import org.apache.hadoop.yarn.server.resourcemanager.rmapp.attempt.RMAppAttempt;
@ -146,6 +148,14 @@ public void testPublishApplicationMetrics() throws Exception {
entity.getOtherInfo().get(
ApplicationMetricsConstants.APPLICATION_PRIORITY_INFO));
Assert.assertEquals(app.getAmNodeLabelExpression(), entity.getOtherInfo()
.get(ApplicationMetricsConstants.AM_NODE_LABEL_EXPRESSION));
Assert.assertEquals(
app.getApplicationSubmissionContext().getNodeLabelExpression(),
entity.getOtherInfo()
.get(ApplicationMetricsConstants.APP_NODE_LABEL_EXPRESSION));
Assert
.assertEquals(
app.getUser(),
@ -351,7 +361,7 @@ public void testPublishContainerMetrics() throws Exception {
}
private static RMApp createRMApp(ApplicationId appId) {
RMApp app = mock(RMApp.class);
RMApp app = mock(RMAppImpl.class);
when(app.getApplicationId()).thenReturn(appId);
when(app.getName()).thenReturn("test app");
when(app.getApplicationType()).thenReturn("test app type");
@ -376,8 +386,14 @@ private static RMApp createRMApp(ApplicationId appId) {
when(app.getApplicationTags()).thenReturn(appTags);
ApplicationSubmissionContext asc = mock(ApplicationSubmissionContext.class);
when(asc.getUnmanagedAM()).thenReturn(false);
when(asc.getPriority()).thenReturn(Priority.newInstance(0));
when(asc.getPriority()).thenReturn(Priority.newInstance(10));
when(asc.getNodeLabelExpression()).thenReturn("high-cpu");
when(app.getApplicationSubmissionContext()).thenReturn(asc);
when(app.getAppNodeLabelExpression()).thenCallRealMethod();
ResourceRequest amReq = mock(ResourceRequest.class);
when(amReq.getNodeLabelExpression()).thenReturn("high-mem");
when(app.getAMResourceRequest()).thenReturn(amReq);
when(app.getAmNodeLabelExpression()).thenCallRealMethod();
return app;
}

View File

@ -31,6 +31,7 @@
import org.apache.hadoop.yarn.api.records.FinalApplicationStatus;
import org.apache.hadoop.yarn.api.records.LogAggregationStatus;
import org.apache.hadoop.yarn.api.records.NodeId;
import org.apache.hadoop.yarn.api.records.Priority;
import org.apache.hadoop.yarn.api.records.ReservationId;
import org.apache.hadoop.yarn.api.records.Resource;
import org.apache.hadoop.yarn.api.records.ResourceRequest;
@ -64,6 +65,8 @@ public MockRMApp(int newid, long time, RMAppState newState) {
finish = time;
id = MockApps.newAppID(newid);
state = newState;
amReq = ResourceRequest.newInstance(Priority.UNDEFINED, "0.0.0.0",
Resource.newInstance(0, 0), 1);
}
public MockRMApp(int newid, long time, RMAppState newState, String userName) {
@ -283,4 +286,14 @@ public Map<NodeId, LogAggregationReport> getLogAggregationReportsForApp() {
public LogAggregationStatus getLogAggregationStatusForAppReport() {
return null;
}
@Override
public String getAmNodeLabelExpression() {
return null;
}
@Override
public String getAppNodeLabelExpression() {
return null;
}
}

View File

@ -261,10 +261,9 @@ protected RMApp createNewTestApp(ApplicationSubmissionContext submissionContext)
// but applicationId is still set for safety
submissionContext.setApplicationId(applicationId);
RMApp application =
new RMAppImpl(applicationId, rmContext, conf, name, user, queue,
submissionContext, scheduler, masterService,
System.currentTimeMillis(), "YARN", null, null);
RMApp application = new RMAppImpl(applicationId, rmContext, conf, name,
user, queue, submissionContext, scheduler, masterService,
System.currentTimeMillis(), "YARN", null, mock(ResourceRequest.class));
testAppStartState(applicationId, user, name, queue, application);
this.rmContext.getRMApps().putIfAbsent(application.getApplicationId(),

View File

@ -1310,14 +1310,29 @@ public void verifyAppsXML(NodeList nodes, RMApp app) throws JSONException,
WebServicesTestUtils.getXmlInt(element, "numNonAMContainerPreempted"),
WebServicesTestUtils.getXmlInt(element, "numAMContainerPreempted"),
WebServicesTestUtils.getXmlString(element, "logAggregationStatus"),
WebServicesTestUtils.getXmlBoolean(element, "unmanagedApplication"));
WebServicesTestUtils.getXmlBoolean(element, "unmanagedApplication"),
WebServicesTestUtils.getXmlString(element, "appNodeLabelExpression"),
WebServicesTestUtils.getXmlString(element, "amNodeLabelExpression"));
}
}
public void verifyAppInfo(JSONObject info, RMApp app) throws JSONException,
Exception {
assertEquals("incorrect number of elements", 30, info.length());
int expectedNumberOfElements = 30;
String appNodeLabelExpression = null;
String amNodeLabelExpression = null;
if (app.getApplicationSubmissionContext()
.getNodeLabelExpression() != null) {
expectedNumberOfElements++;
appNodeLabelExpression = info.getString("appNodeLabelExpression");
}
if (app.getAMResourceRequest().getNodeLabelExpression() != null) {
expectedNumberOfElements++;
amNodeLabelExpression = info.getString("amNodeLabelExpression");
}
assertEquals("incorrect number of elements", expectedNumberOfElements,
info.length());
verifyAppInfoGeneric(app, info.getString("id"), info.getString("user"),
info.getString("name"), info.getString("applicationType"),
@ -1334,7 +1349,9 @@ public void verifyAppInfo(JSONObject info, RMApp app) throws JSONException,
info.getInt("numNonAMContainerPreempted"),
info.getInt("numAMContainerPreempted"),
info.getString("logAggregationStatus"),
info.getBoolean("unmanagedApplication"));
info.getBoolean("unmanagedApplication"),
appNodeLabelExpression,
amNodeLabelExpression);
}
public void verifyAppInfoGeneric(RMApp app, String id, String user,
@ -1345,7 +1362,8 @@ public void verifyAppInfoGeneric(RMApp app, String id, String user,
int allocatedMB, int allocatedVCores, int numContainers,
int preemptedResourceMB, int preemptedResourceVCores,
int numNonAMContainerPreempted, int numAMContainerPreempted,
String logAggregationStatus, boolean unmanagedApplication)
String logAggregationStatus, boolean unmanagedApplication,
String appNodeLabelExpression, String amNodeLabelExpression)
throws JSONException,
Exception {
@ -1400,6 +1418,12 @@ public void verifyAppInfoGeneric(RMApp app, String id, String user,
assertEquals("unmanagedApplication doesn't match", app
.getApplicationSubmissionContext().getUnmanagedAM(),
unmanagedApplication);
assertEquals("unmanagedApplication doesn't match",
app.getApplicationSubmissionContext().getNodeLabelExpression(),
appNodeLabelExpression);
assertEquals("unmanagedApplication doesn't match",
app.getAMResourceRequest().getNodeLabelExpression(),
amNodeLabelExpression);
}
@Test

View File

@ -1379,11 +1379,13 @@ Response Body:
"allocatedVCores" : 0,
"runningContainers" : 0,
"applicationType" : "MAPREDUCE",
"applicationTags" : ""
"applicationTags" : "",
"memorySeconds" : 151730,
"vcoreSeconds" : 103,
"unmanagedApplication":"false"
"applicationPriority":0
"unmanagedApplication" : "false",
"applicationPriority" : 0,
"appNodeLabelExpression" : "",
"amnodeLabelExpression" : ""
},
{
"finishedTime" : 1326815789546,
@ -1406,11 +1408,13 @@ Response Body:
"allocatedVCores" : 0,
"runningContainers" : 1,
"applicationType" : "YARN",
"applicationTags" : "tag1"
"applicationTags" : "tag1",
"memorySeconds" : 640064,
"vcoreSeconds" : 442
"unmanagedApplication":"false"
"applicationPriority":0
"vcoreSeconds" : 442,
"unmanagedApplication" : "false",
"applicationPriority" : 0,
"appNodeLabelExpression" : "",
"amNodeLabelExpression" : ""
}
]
}
@ -1462,6 +1466,8 @@ Response Body:
<vcoreSeconds>103</vcoreSeconds>
<unmanagedApplication>false</unmanagedApplication>
<applicationPriority>0</applicationPriority>
<appNodeLabelExpression></appNodeLabelExpression>
<amNodeLabelExpression></amNodeLabelExpression>
</app>
<app>
<id>application_1326815542473_0002</id>
@ -1489,6 +1495,8 @@ Response Body:
<vcoreSeconds>442</vcoreSeconds>
<unmanagedApplication>false</unmanagedApplication>
<applicationPriority>0</applicationPriority>
<appNodeLabelExpression></appNodeLabelExpression>
<amNodeLabelExpression></amNodeLabelExpression>
</app>
</apps>
```
@ -1650,6 +1658,8 @@ Note that depending on security settings a user might not be able to see all the
| vcoreSeconds | long | The amount of CPU resources the application has allocated (virtual core-seconds) |
| unmanagedApplication | boolean | Is the application unmanaged. |
| applicationPriority | int | priority of the submitted application |
| appNodeLabelExpression | string | Node Label expression which is used to identify the nodes on which application's containers are expected to run by default.|
| amNodeLabelExpression | string | Node Label expression which is used to identify the node on which application's AM container is expected to run.|
### Response Examples
@ -1690,8 +1700,10 @@ Response Body:
"queue" : "a1",
"memorySeconds" : 151730,
"vcoreSeconds" : 103,
"unmanagedApplication":"false"
"applicationPriority":0
"unmanagedApplication" : "false",
"applicationPriority" : 0,
"appNodeLabelExpression" : "",
"amNodeLabelExpression" : ""
}
}
```
@ -1735,6 +1747,8 @@ Response Body:
<vcoreSeconds>103</vcoreSeconds>
<unmanagedApplication>false</unmanagedApplication>
<applicationPriority>0</applicationPriority>
<appNodeLabelExpression></appNodeLabelExpression>
<amNodeLabelExpression></amNodeLabelExpression>
</app>
```

View File

@ -1089,7 +1089,10 @@ Response Body:
"finishedTime":1430425008861,
"elapsedTime":7857,
"unmanagedApplication":"false",
"applicationPriority":0},
"applicationPriority":0,
"appNodeLabelExpression":"",
"amNodeLabelExpression":""
},
{
"appId":"application_1430424020775_0003",
"currentAppAttemptId":"appattempt_1430424020775_0003_000001",
@ -1110,7 +1113,10 @@ Response Body:
"finishedTime":1430424963907,
"elapsedTime":7257,
"unmanagedApplication":"false",
"applicationPriority":0},
"applicationPriority":0,
"appNodeLabelExpression":"",
"amNodeLabelExpression":""
},
{
"appId":"application_1430424020775_0002",
"currentAppAttemptId":"appattempt_1430424020775_0002_000001",
@ -1131,7 +1137,10 @@ Response Body:
"finishedTime":1430424776594,
"elapsedTime":7199,
"unmanagedApplication":"false",
"applicationPriority":0},
"applicationPriority":0,
"appNodeLabelExpression":"",
"amNodeLabelExpression":""
},
{
"appId":"application_1430424020775_0001",
"currentAppAttemptId":"appattempt_1430424020775_0001_000001",
@ -1153,7 +1162,9 @@ Response Body:
"elapsedTime":18344,
"applicationTags":"mrapplication,ta-example",
"unmanagedApplication":"false",
"applicationPriority":0
"applicationPriority":0,
"appNodeLabelExpression":"",
"amNodeLabelExpression":""
}
]
}
@ -1197,6 +1208,8 @@ Response Body:
<elapsedTime>7857</elapsedTime>
<unmanagedApplication>false</unmanagedApplication>
<applicationPriority>0</applicationPriority>
<appNodeLabelExpression></appNodeLabelExpression>
<amNodeLabelExpression></amNodeLabelExpression>
</app>
<app>
<appId>application_1430424020775_0003</appId>
@ -1219,6 +1232,8 @@ Response Body:
<elapsedTime>7257</elapsedTime>
<unmanagedApplication>false</unmanagedApplication>
<applicationPriority>0</applicationPriority>
<appNodeLabelExpression></appNodeLabelExpression>
<amNodeLabelExpression></amNodeLabelExpression>
</app>
<app>
<appId>application_1430424020775_0002</appId>
@ -1241,6 +1256,8 @@ Response Body:
<elapsedTime>7199</elapsedTime>
<unmanagedApplication>false</unmanagedApplication>
<applicationPriority>0</applicationPriority>
<appNodeLabelExpression></appNodeLabelExpression>
<amNodeLabelExpression></amNodeLabelExpression>
</app>
<app>
<appId>application_1430424020775_0001</appId>
@ -1264,6 +1281,8 @@ Response Body:
<applicationTags>mrapplication,ta-example</applicationTags>
<unmanagedApplication>false</unmanagedApplication>
<applicationPriority>0</applicationPriority>
<appNodeLabelExpression></appNodeLabelExpression>
<amNodeLabelExpression></amNodeLabelExpression>
</app>
</apps>
@ -1316,7 +1335,8 @@ None
| `applicationTags` | string | The application tags. |
| `unmanagedApplication` | boolean | Is the application unmanaged. |
| `applicationPriority` | int | Priority of the submitted application. |
| `appNodeLabelExpression` | string |Node Label expression which is used to identify the nodes on which application's containers are expected to run by default.|
| `amNodeLabelExpression` | string | Node Label expression which is used to identify the node on which application's AM container is expected to run.|
### Response Examples:
#### JSON response
@ -1353,8 +1373,10 @@ Response Body:
"finishedTime": 1430424072153,
"elapsedTime": 18344,
"applicationTags": mrapplication,tag-example,
"unmanagedApplication":"false"
"applicationPriority":0
"unmanagedApplication": "false",
"applicationPriority": 0,
"appNodeLabelExpression": "",
"amNodeLabelExpression": ""
}
#### XML response
@ -1395,6 +1417,8 @@ Response Body:
<applicationTags>mrapplication,ta-example</applicationTags>
<unmanagedApplication>false</unmanagedApplication>
<applicationPriority>0</applicationPriority>
<appNodeLabelExpression><appNodeLabelExpression>
<amNodeLabelExpression><amNodeLabelExpression>
</app>
## <a name="REST_API_APPLICATION_ATTEMPT_LIST"></a>Application Attempt List