YARN-4609. RM Nodes list page takes too much time to load. Contributed by Bibin A Chundatt

(cherry picked from commit 776b549e2a)
This commit is contained in:
Rohith Sharma K S 2016-04-05 14:47:25 +05:30
parent eec23580b4
commit 13a4e25f26
2 changed files with 45 additions and 45 deletions

View File

@ -18,8 +18,8 @@
package org.apache.hadoop.yarn.server.resourcemanager.webapp; package org.apache.hadoop.yarn.server.resourcemanager.webapp;
import static org.apache.hadoop.yarn.webapp.YarnWebParams.NODE_STATE;
import static org.apache.hadoop.yarn.webapp.YarnWebParams.NODE_LABEL; import static org.apache.hadoop.yarn.webapp.YarnWebParams.NODE_LABEL;
import static org.apache.hadoop.yarn.webapp.YarnWebParams.NODE_STATE;
import static org.apache.hadoop.yarn.webapp.view.JQueryUI.DATATABLES; import static org.apache.hadoop.yarn.webapp.view.JQueryUI.DATATABLES;
import static org.apache.hadoop.yarn.webapp.view.JQueryUI.DATATABLES_ID; import static org.apache.hadoop.yarn.webapp.view.JQueryUI.DATATABLES_ID;
import static org.apache.hadoop.yarn.webapp.view.JQueryUI.initID; import static org.apache.hadoop.yarn.webapp.view.JQueryUI.initID;
@ -40,7 +40,6 @@ import org.apache.hadoop.yarn.webapp.SubView;
import org.apache.hadoop.yarn.webapp.hamlet.Hamlet; import org.apache.hadoop.yarn.webapp.hamlet.Hamlet;
import org.apache.hadoop.yarn.webapp.hamlet.Hamlet.TABLE; import org.apache.hadoop.yarn.webapp.hamlet.Hamlet.TABLE;
import org.apache.hadoop.yarn.webapp.hamlet.Hamlet.TBODY; import org.apache.hadoop.yarn.webapp.hamlet.Hamlet.TBODY;
import org.apache.hadoop.yarn.webapp.hamlet.Hamlet.TR;
import org.apache.hadoop.yarn.webapp.view.HtmlBlock; import org.apache.hadoop.yarn.webapp.view.HtmlBlock;
import com.google.inject.Inject; import com.google.inject.Inject;
@ -101,6 +100,7 @@ class NodesPage extends RmView {
LOG.debug("Unexpected state filter for inactive RM node"); LOG.debug("Unexpected state filter for inactive RM node");
} }
} }
StringBuilder nodeTableData = new StringBuilder("[\n");
for (RMNode ni : rmNodes) { for (RMNode ni : rmNodes) {
if (stateFilter != null) { if (stateFilter != null) {
NodeState state = ni.getState(); NodeState state = ni.getState();
@ -129,27 +129,40 @@ class NodesPage extends RmView {
NodeInfo info = new NodeInfo(ni, sched); NodeInfo info = new NodeInfo(ni, sched);
int usedMemory = (int) info.getUsedMemory(); int usedMemory = (int) info.getUsedMemory();
int availableMemory = (int) info.getAvailableMemory(); int availableMemory = (int) info.getAvailableMemory();
TR<TBODY<TABLE<Hamlet>>> row = nodeTableData.append("[\"")
tbody.tr().td(StringUtils.join(",", info.getNodeLabels())) .append(StringUtils.join(",", info.getNodeLabels())).append("\",\"")
.td(info.getRack()).td(info.getState()).td(info.getNodeId()); .append(info.getRack()).append("\",\"").append(info.getState())
.append("\",\"").append(info.getNodeId());
if (isInactive) { if (isInactive) {
row.td()._("N/A")._(); nodeTableData.append("\",\"").append("N/A").append("\",\"");
} else { } else {
String httpAddress = info.getNodeHTTPAddress(); String httpAddress = info.getNodeHTTPAddress();
row.td().a("//" + httpAddress, httpAddress)._(); nodeTableData.append("\",\"<a ").append("href='" + "//" + httpAddress)
.append("'>").append(httpAddress).append("</a>\",").append("\"");
} }
row.td().br().$title(String.valueOf(info.getLastHealthUpdate()))._() nodeTableData.append("<br title='")
._(Times.format(info.getLastHealthUpdate()))._() .append(String.valueOf(info.getLastHealthUpdate())).append("'>")
.td(info.getHealthReport()) .append(Times.format(info.getLastHealthUpdate())).append("\",\"")
.td(String.valueOf(info.getNumContainers())).td().br() .append(info.getHealthReport()).append("\",\"")
.$title(String.valueOf(usedMemory))._() .append(String.valueOf(info.getNumContainers())).append("\",\"")
._(StringUtils.byteDesc(usedMemory * BYTES_IN_MB))._().td().br() .append("<br title='").append(String.valueOf(usedMemory))
.$title(String.valueOf(availableMemory))._() .append("'>").append(StringUtils.byteDesc(usedMemory * BYTES_IN_MB))
._(StringUtils.byteDesc(availableMemory * BYTES_IN_MB))._() .append("\",\"").append("<br title='")
.td(String.valueOf(info.getUsedVirtualCores())) .append(String.valueOf(availableMemory)).append("'>")
.td(String.valueOf(info.getAvailableVirtualCores())) .append(StringUtils.byteDesc(availableMemory * BYTES_IN_MB))
.td(ni.getNodeManagerVersion())._(); .append("\",\"").append(String.valueOf(info.getUsedVirtualCores()))
.append("\",\"")
.append(String.valueOf(info.getAvailableVirtualCores()))
.append("\",\"").append(ni.getNodeManagerVersion())
.append("\"],\n");
} }
if (nodeTableData.charAt(nodeTableData.length() - 2) == ',') {
nodeTableData.delete(nodeTableData.length() - 2,
nodeTableData.length() - 1);
}
nodeTableData.append("]");
html.script().$type("text/javascript")
._("var nodeTableData=" + nodeTableData)._();
tbody._()._(); tbody._()._();
} }
} }
@ -175,7 +188,9 @@ class NodesPage extends RmView {
} }
private String nodesTableInit() { private String nodesTableInit() {
StringBuilder b = tableInit().append(", aoColumnDefs: ["); StringBuilder b = tableInit().append(", 'aaData': nodeTableData")
.append(", bDeferRender: true").append(", bProcessing: true")
.append(", aoColumnDefs: [");
b.append("{'bSearchable': false, 'aTargets': [ 7 ]}"); b.append("{'bSearchable': false, 'aTargets': [ 7 ]}");
b.append(", {'sType': 'title-numeric', 'bSearchable': false, " b.append(", {'sType': 'title-numeric', 'bSearchable': false, "
+ "'aTargets': [ 8, 9 ] }"); + "'aTargets': [ 8, 9 ] }");

View File

@ -81,11 +81,8 @@ public class TestNodesPage {
Mockito.verify(writer, Mockito.verify(writer,
Mockito.times(numberOfActualTableHeaders + numberOfThInMetricsTable)) Mockito.times(numberOfActualTableHeaders + numberOfThInMetricsTable))
.print("<th"); .print("<th");
Mockito.verify( Mockito.verify(writer, Mockito.times(numberOfThInMetricsTable))
writer, .print("<td");
Mockito.times(numberOfRacks * numberOfNodesPerRack
* numberOfActualTableHeaders + numberOfThInMetricsTable)).print(
"<td");
} }
@Test @Test
@ -99,11 +96,8 @@ public class TestNodesPage {
Mockito.verify(writer, Mockito.verify(writer,
Mockito.times(numberOfActualTableHeaders + numberOfThInMetricsTable)) Mockito.times(numberOfActualTableHeaders + numberOfThInMetricsTable))
.print("<th"); .print("<th");
Mockito.verify( Mockito.verify(writer, Mockito.times(numberOfThInMetricsTable))
writer, .print("<td");
Mockito.times(numberOfRacks * numberOfLostNodesPerRack
* numberOfActualTableHeaders + numberOfThInMetricsTable)).print(
"<td");
} }
@Test @Test
@ -113,12 +107,9 @@ public class TestNodesPage {
nodesBlock.render(); nodesBlock.render();
PrintWriter writer = injector.getInstance(PrintWriter.class); PrintWriter writer = injector.getInstance(PrintWriter.class);
WebAppTests.flushOutput(injector); WebAppTests.flushOutput(injector);
Mockito.verify(writer, Mockito.times(numberOfThInMetricsTable))
Mockito.verify( .print("<td");
writer, Mockito.verify(writer, Mockito.times(1)).print("<script");
Mockito.times(numberOfRacks
* numberOfActualTableHeaders + numberOfThInMetricsTable)).print(
"<td");
} }
@Test @Test
@ -129,11 +120,8 @@ public class TestNodesPage {
PrintWriter writer = injector.getInstance(PrintWriter.class); PrintWriter writer = injector.getInstance(PrintWriter.class);
WebAppTests.flushOutput(injector); WebAppTests.flushOutput(injector);
Mockito.verify( Mockito.verify(writer, Mockito.times(numberOfThInMetricsTable))
writer, .print("<td");
Mockito.times(numberOfRacks * (numberOfNodesPerRack - 1)
* numberOfActualTableHeaders + numberOfThInMetricsTable)).print(
"<td");
} }
@Test @Test
@ -144,10 +132,7 @@ public class TestNodesPage {
PrintWriter writer = injector.getInstance(PrintWriter.class); PrintWriter writer = injector.getInstance(PrintWriter.class);
WebAppTests.flushOutput(injector); WebAppTests.flushOutput(injector);
Mockito.verify( Mockito.verify(writer, Mockito.times(numberOfThInMetricsTable))
writer, .print("<td");
Mockito.times(numberOfRacks * numberOfNodesPerRack
* numberOfActualTableHeaders + numberOfThInMetricsTable)).print(
"<td");
} }
} }