You are viewing a plain text version of this content. The canonical link for it is here.
Posted to common-commits@hadoop.apache.org by cu...@apache.org on 2006/11/21 20:53:41 UTC
svn commit: r477850 - in /lucene/hadoop/trunk: ./
src/java/org/apache/hadoop/dfs/ src/webapps/dfs/ src/webapps/static/
Author: cutting
Date: Tue Nov 21 11:53:40 2006
New Revision: 477850
URL: http://svn.apache.org/viewvc?view=rev&rev=477850
Log:
HADOOP-699. Fix DFS web interface port number problem. Contributed by Raghu.
Modified:
lucene/hadoop/trunk/CHANGES.txt
lucene/hadoop/trunk/src/java/org/apache/hadoop/dfs/DataNode.java
lucene/hadoop/trunk/src/java/org/apache/hadoop/dfs/DatanodeDescriptor.java
lucene/hadoop/trunk/src/java/org/apache/hadoop/dfs/DatanodeID.java
lucene/hadoop/trunk/src/java/org/apache/hadoop/dfs/FSNamesystem.java
lucene/hadoop/trunk/src/java/org/apache/hadoop/dfs/JspHelper.java
lucene/hadoop/trunk/src/webapps/dfs/dfshealth.jsp
lucene/hadoop/trunk/src/webapps/static/hadoop.css
Modified: lucene/hadoop/trunk/CHANGES.txt
URL: http://svn.apache.org/viewvc/lucene/hadoop/trunk/CHANGES.txt?view=diff&rev=477850&r1=477849&r2=477850
==============================================================================
--- lucene/hadoop/trunk/CHANGES.txt (original)
+++ lucene/hadoop/trunk/CHANGES.txt Tue Nov 21 11:53:40 2006
@@ -111,6 +111,11 @@
the format of IPC requests back-compatibly in subsequent releases.
(omalley via cutting)
+34. HADOOP-699. Fix DFS web interface so that filesystem browsing
+ works correctly, using the right port number. Also add support
+ for sorting datanode list by various columns.
+ (Raghu Angadi via cutting)
+
Release 0.8.0 - 2006-11-03
Modified: lucene/hadoop/trunk/src/java/org/apache/hadoop/dfs/DataNode.java
URL: http://svn.apache.org/viewvc/lucene/hadoop/trunk/src/java/org/apache/hadoop/dfs/DataNode.java?view=diff&rev=477850&r1=477849&r2=477850
==============================================================================
--- lucene/hadoop/trunk/src/java/org/apache/hadoop/dfs/DataNode.java (original)
+++ lucene/hadoop/trunk/src/java/org/apache/hadoop/dfs/DataNode.java Tue Nov 21 11:53:40 2006
@@ -158,8 +158,6 @@
this(InetAddress.getLocalHost().getHostName(),
dataDirs,
createSocketAddr(conf.get("fs.default.name", "local")), conf);
- // register datanode
- register();
int infoServerPort = conf.getInt("dfs.datanode.info.port", 50075);
String infoServerBindAddress = conf.get("dfs.datanode.info.bindAddress", "0.0.0.0");
this.infoServer = new StatusHttpServer("datanode", infoServerBindAddress, infoServerPort, true);
@@ -167,6 +165,8 @@
this.infoServer.addServlet(null, "/streamFile/*", StreamFile.class);
this.infoServer.start();
this.dnRegistration.infoPort = this.infoServer.getPort();
+ // register datanode
+ register();
datanodeObject = this;
}
Modified: lucene/hadoop/trunk/src/java/org/apache/hadoop/dfs/DatanodeDescriptor.java
URL: http://svn.apache.org/viewvc/lucene/hadoop/trunk/src/java/org/apache/hadoop/dfs/DatanodeDescriptor.java?view=diff&rev=477850&r1=477849&r2=477850
==============================================================================
--- lucene/hadoop/trunk/src/java/org/apache/hadoop/dfs/DatanodeDescriptor.java (original)
+++ lucene/hadoop/trunk/src/java/org/apache/hadoop/dfs/DatanodeDescriptor.java Tue Nov 21 11:53:40 2006
@@ -74,6 +74,10 @@
this.xceiverCount = 0;
this.blocks.clear();
}
+
+ int numBlocks() {
+ return blocks.size();
+ }
/**
*/
Modified: lucene/hadoop/trunk/src/java/org/apache/hadoop/dfs/DatanodeID.java
URL: http://svn.apache.org/viewvc/lucene/hadoop/trunk/src/java/org/apache/hadoop/dfs/DatanodeID.java?view=diff&rev=477850&r1=477849&r2=477850
==============================================================================
--- lucene/hadoop/trunk/src/java/org/apache/hadoop/dfs/DatanodeID.java (original)
+++ lucene/hadoop/trunk/src/java/org/apache/hadoop/dfs/DatanodeID.java Tue Nov 21 11:53:40 2006
@@ -94,6 +94,16 @@
return name;
}
+ /**
+ * Update fields when a new registration request comes in.
+ * Note that this does not update storageID.
+ */
+ void updateRegInfo( DatanodeID nodeReg ) {
+ name = nodeReg.getName();
+ infoPort = nodeReg.getInfoPort();
+ // update any more fields added in future.
+ }
+
/** Comparable.
* Basis of compare is the String name (host:portNumber) only.
* @param o
Modified: lucene/hadoop/trunk/src/java/org/apache/hadoop/dfs/FSNamesystem.java
URL: http://svn.apache.org/viewvc/lucene/hadoop/trunk/src/java/org/apache/hadoop/dfs/FSNamesystem.java?view=diff&rev=477850&r1=477849&r2=477850
==============================================================================
--- lucene/hadoop/trunk/src/java/org/apache/hadoop/dfs/FSNamesystem.java (original)
+++ lucene/hadoop/trunk/src/java/org/apache/hadoop/dfs/FSNamesystem.java Tue Nov 21 11:53:40 2006
@@ -1198,17 +1198,7 @@
DatanodeDescriptor nodeS = datanodeMap.get(nodeReg.getStorageID());
DatanodeDescriptor nodeN = getDatanodeByName( nodeReg.getName() );
- if( nodeN != null && nodeS != null && nodeN == nodeS ) {
- // The same datanode has been just restarted to serve the same data
- // storage. We do not need to remove old data blocks, the delta will
- // be calculated on the next block report from the datanode
- NameNode.stateChangeLog.info(
- "BLOCK* NameSystem.registerDatanode: "
- + "node restarted." );
- return;
- }
-
- if( nodeN != null ) {
+ if( nodeN != null && nodeN != nodeS ) {
// nodeN previously served a different data storage,
// which is not served by anybody anymore.
removeDatanode( nodeN );
@@ -1218,18 +1208,25 @@
getEditLog().logRemoveDatanode( nodeN );
nodeN = null;
}
-
- // nodeN is not found
- if( nodeS != null ) {
- // nodeS is found
- // The registering datanode is a replacement node for the existing
- // data storage, which from now on will be served by a new node.
- NameNode.stateChangeLog.debug(
+
+ if ( nodeS != null ) {
+ if( nodeN == nodeS ) {
+ // The same datanode has been just restarted to serve the same data
+ // storage. We do not need to remove old data blocks, the delta will
+ // be calculated on the next block report from the datanode
+ NameNode.stateChangeLog.debug("BLOCK* NameSystem.registerDatanode: "
+ + "node restarted." );
+ } else {
+ // nodeS is found
+ // The registering datanode is a replacement node for the existing
+ // data storage, which from now on will be served by a new node.
+ NameNode.stateChangeLog.debug(
"BLOCK* NameSystem.registerDatanode: "
+ "node " + nodeS.name
+ " is replaced by " + nodeReg.getName() + "." );
+ }
getEditLog().logRemoveDatanode( nodeS );
- nodeS.name = nodeReg.getName();
+ nodeS.updateRegInfo( nodeReg );
getEditLog().logAddDatanode( nodeS );
return;
}
@@ -1763,8 +1760,8 @@
/**
*/
- public void DFSNodesStatus( Vector<DatanodeDescriptor> live,
- Vector<DatanodeDescriptor> dead) {
+ public void DFSNodesStatus( ArrayList<DatanodeDescriptor> live,
+ ArrayList<DatanodeDescriptor> dead ) {
synchronized (heartbeats) {
synchronized (datanodeMap) {
for(Iterator<DatanodeDescriptor> it = datanodeMap.values().iterator(); it.hasNext(); ) {
Modified: lucene/hadoop/trunk/src/java/org/apache/hadoop/dfs/JspHelper.java
URL: http://svn.apache.org/viewvc/lucene/hadoop/trunk/src/java/org/apache/hadoop/dfs/JspHelper.java?view=diff&rev=477850&r1=477849&r2=477850
==============================================================================
--- lucene/hadoop/trunk/src/java/org/apache/hadoop/dfs/JspHelper.java (original)
+++ lucene/hadoop/trunk/src/java/org/apache/hadoop/dfs/JspHelper.java Tue Nov 21 11:53:40 2006
@@ -140,16 +140,10 @@
in.close();
out.print(new String(buf));
}
- public void DFSNodesStatus(Vector live, Vector dead) {
- if (fsn == null) return;
- TreeMap nodesSortedByName = new TreeMap();
- fsn.DFSNodesStatus(live, dead);
- for (int num = 0; num < live.size(); num++) {
- DatanodeInfo d = (DatanodeInfo)live.elementAt(num);
- nodesSortedByName.put(d.getName(), d);
- }
- live.clear();
- live.addAll(nodesSortedByName.values());
+ public void DFSNodesStatus( ArrayList<DatanodeDescriptor> live,
+ ArrayList<DatanodeDescriptor> dead ) {
+ if ( fsn != null )
+ fsn.DFSNodesStatus(live, dead);
}
public void addTableHeader(JspWriter out) throws IOException {
out.print("<table border=\"1\""+
@@ -183,6 +177,72 @@
public String getSafeModeText() {
if( ! fsn.isInSafeMode() )
return "";
- return "Safe mode is ON. <em>" + fsn.getSafeModeTip() + "</em>";
+ return "Safe mode is ON. <em>" + fsn.getSafeModeTip() + "</em><br>";
+ }
+
+ public void sortNodeList(ArrayList<DatanodeDescriptor> nodes,
+ String field, String order) {
+
+ class NodeComapare implements Comparator<DatanodeDescriptor> {
+ static final int
+ FIELD_NAME = 1,
+ FIELD_LAST_CONTACT = 2,
+ FIELD_BLOCKS = 3,
+ FIELD_SIZE = 4,
+ FIELD_DISK_USED = 5,
+ SORT_ORDER_ASC = 1,
+ SORT_ORDER_DSC = 2;
+
+ int sortField = FIELD_NAME;
+ int sortOrder = SORT_ORDER_ASC;
+
+ public NodeComapare(String field, String order) {
+ if ( field.equals( "lastcontact" ) ) {
+ sortField = FIELD_LAST_CONTACT;
+ } else if ( field.equals( "size" ) ) {
+ sortField = FIELD_SIZE;
+ } else if ( field.equals( "blocks" ) ) {
+ sortField = FIELD_BLOCKS;
+ } else if ( field.equals( "pcused" ) ) {
+ sortField = FIELD_DISK_USED;
+ } else {
+ sortField = FIELD_NAME;
+ }
+
+ if ( order.equals("DSC") ) {
+ sortOrder = SORT_ORDER_DSC;
+ } else {
+ sortOrder = SORT_ORDER_ASC;
+ }
+ }
+
+ public int compare( DatanodeDescriptor d1,
+ DatanodeDescriptor d2 ) {
+ int ret = 0;
+ switch ( sortField ) {
+ case FIELD_LAST_CONTACT:
+ ret = (int) (d2.getLastUpdate() - d1.getLastUpdate());
+ break;
+ case FIELD_BLOCKS:
+ ret = d1.numBlocks() - d2.numBlocks();
+ break;
+ case FIELD_SIZE:
+ long dlong = d1.getCapacity() - d2.getCapacity();
+ ret = (dlong < 0) ? -1 : ( (dlong > 0) ? 1 : 0 );
+ break;
+ case FIELD_DISK_USED:
+ double ddbl =((d2.getRemaining()*1.0/d2.getCapacity())-
+ (d1.getRemaining()*1.0/d1.getCapacity()));
+ ret = (ddbl < 0) ? -1 : ( (ddbl > 0) ? 1 : 0 );
+ break;
+ case FIELD_NAME:
+ ret = d1.getName().compareTo(d2.getName());
+ break;
+ }
+ return ( sortOrder == SORT_ORDER_DSC ) ? -ret : ret;
+ }
+ }
+
+ Collections.sort( nodes, new NodeComapare( field, order ) );
}
}
Modified: lucene/hadoop/trunk/src/webapps/dfs/dfshealth.jsp
URL: http://svn.apache.org/viewvc/lucene/hadoop/trunk/src/webapps/dfs/dfshealth.jsp?view=diff&rev=477850&r1=477849&r2=477850
==============================================================================
--- lucene/hadoop/trunk/src/webapps/dfs/dfshealth.jsp (original)
+++ lucene/hadoop/trunk/src/webapps/dfs/dfshealth.jsp Tue Nov 21 11:53:40 2006
@@ -15,8 +15,52 @@
long currentTime;
JspHelper jspHelper = new JspHelper();
- public void generateLiveNodeData(JspWriter out, DatanodeInfo d)
+ int rowNum = 0;
+ int colNum = 0;
+
+ String rowTxt() { colNum = 0;
+ return "<tr class=\"" + (((rowNum++)%2 == 0)? "rowNormal" : "rowAlt")
+ + "\"> "; }
+ String colTxt() { return "<td id=\"col" + ++colNum + "\"> "; }
+ void counterReset () { colNum = 0; rowNum = 0 ; }
+
+ long diskBytes = 1024 * 1024 * 1024;
+ String diskByteStr = "GB";
+
+ String sorterField = null;
+ String sorterOrder = null;
+
+ String NodeHeaderStr(String name) {
+ String ret = "class=header";
+ String order = "ASC";
+ if ( name.equals( sorterField ) ) {
+ ret += sorterOrder;
+ if ( sorterOrder.equals("ASC") )
+ order = "DSC";
+ }
+ ret += " onClick=\"window.document.location=" +
+ "'/dfshealth.jsp?sorter/field=" + name + "&sorter/order=" +
+ order + "'\" title=\"sort on this column\"";
+
+ return ret;
+ }
+
+ public void generateLiveNodeData( JspWriter out, DatanodeDescriptor d,
+ String suffix, boolean alive )
throws IOException {
+
+ String name = d.getName();
+ if ( !name.matches( "\\d+\\.\\d+.\\d+\\.\\d+.*" ) )
+ name = name.replaceAll( "\\.[^.:]*", "" );
+
+ int idx = (suffix != null && name.endsWith( suffix )) ?
+ name.indexOf( suffix ) : -1;
+ out.print( rowTxt() + "<td class=\"name\"><a title=\"" + d.getName() +
+ "\">" + (( idx > 0 ) ? name.substring(0, idx) : name) +
+ (( alive ) ? "" : "\n") );
+ if ( !alive )
+ return;
+
long c = d.getCapacity();
long r = d.getRemaining();
long u = c - r;
@@ -27,66 +71,112 @@
else
percentUsed = "100";
- out.print("<tr> <td id=\"col1\">" + d.getName() +
- "<td>" + ((currentTime - d.getLastUpdate())/1000) +
- "<td>" + DFSShell.byteDesc(c) +
- "<td>" + percentUsed + "\n");
+ out.print("<td class=\"lastcontact\"> " +
+ ((currentTime - d.getLastUpdate())/1000) +
+ "<td class=\"size\">" +
+ DFSShell.limitDecimal(c*1.0/diskBytes, 2) +
+ "<td class=\"pcused\">" + percentUsed +
+ "<td class=\"blocks\">" + d.numBlocks() + "\n");
}
public void generateDFSHealthReport(JspWriter out,
HttpServletRequest request)
throws IOException {
- Vector live = new Vector();
- Vector dead = new Vector();
+ ArrayList<DatanodeDescriptor> live = new ArrayList<DatanodeDescriptor>();
+ ArrayList<DatanodeDescriptor> dead = new ArrayList<DatanodeDescriptor>();
jspHelper.DFSNodesStatus(live, dead);
+
+ sorterField = request.getParameter("sorter/field");
+ sorterOrder = request.getParameter("sorter/order");
+ if ( sorterField == null )
+ sorterField = "name";
+ if ( sorterOrder == null )
+ sorterOrder = "ASC";
+
+ jspHelper.sortNodeList(live, sorterField, sorterOrder);
+ jspHelper.sortNodeList(dead, "name", "ASC");
+
+ // Find out common suffix. Should this be before or after the sort?
+ String port_suffix = null;
+ if ( live.size() > 0 ) {
+ String name = live.get(0).getName();
+ int idx = name.indexOf(':');
+ if ( idx > 0 ) {
+ port_suffix = name.substring( idx );
+ }
+
+ for ( int i=1; port_suffix != null && i < live.size(); i++ ) {
+ if ( live.get(i).getName().endsWith( port_suffix ) == false ) {
+ port_suffix = null;
+ break;
+ }
+ }
+ }
+
+ counterReset();
out.print( "<div id=\"dfstable\"> <table>\n" +
- "<tr> <td id=\"col1\"> Capacity <td> : <td>" +
+ rowTxt() + colTxt() + "Capacity" + colTxt() + ":" + colTxt() +
DFSShell.byteDesc( fsn.totalCapacity() ) +
- "<tr> <td id=\"col1\"> Remaining <td> : <td>" +
+ rowTxt() + colTxt() + "Remaining" + colTxt() + ":" + colTxt() +
DFSShell.byteDesc( fsn.totalRemaining() ) +
- "<tr> <td id=\"col1\"> Used <td> : <td>" +
+ rowTxt() + colTxt() + "Used" + colTxt() + ":" + colTxt() +
DFSShell.limitDecimal((fsn.totalCapacity() -
fsn.totalRemaining())*100.0/
- (fsn.totalCapacity() + 1e-10), 2) +
- "%<tr> <td id=\"col1\"> Live Nodes <td> : <td>" + live.size() +
- "<tr> <td id=\"col1\"> Dead Nodes <td> : <td>" + dead.size() +
+ (fsn.totalCapacity() + 1e-10), 2) + " %" +
+ rowTxt() + colTxt() +
+ "<a href=\"#LiveNodes\">Live Nodes</a> " +
+ colTxt() + ":" + colTxt() + live.size() +
+ rowTxt() + colTxt() +
+ "<a href=\"#DeadNodes\">Dead Nodes</a> " +
+ colTxt() + ":" + colTxt() + dead.size() +
"</table></div><br><hr>\n" );
if (live.isEmpty() && dead.isEmpty()) {
out.print("There are no datanodes in the cluster");
}
else {
-
+
currentTime = System.currentTimeMillis();
out.print( "<div id=\"dfsnodetable\"> "+
- "<a id=\"title\">" +
+ "<a name=\"LiveNodes\" id=\"title\">" +
"Live Datanodes: " + live.size() + "</a>" +
- "<br><br>\n<table border=\"1\">\n" );
+ "<br><br>\n<table border=1 cellspacing=0>\n" );
+ counterReset();
+
if ( live.size() > 0 ) {
+
+ if ( live.get(0).getCapacity() > 1024 * diskBytes ) {
+ diskBytes *= 1024;
+ diskByteStr = "TB";
+ }
- out.print( "<tr id=\"row1\">" +
- "<td> Node <td> Last Contact <td> Size " +
- "<td> Used (%)\n" );
+ out.print( "<tr class=\"headerRow\"> <th " +
+ NodeHeaderStr("name") + "> Node <th " +
+ NodeHeaderStr("lastcontact") + "> Last Contact <th " +
+ NodeHeaderStr("size") + "> Size (" + diskByteStr +
+ ") <th " + NodeHeaderStr("pcused") +
+ "> Used (%) <th " + NodeHeaderStr("blocks") +
+ "> Blocks\n" );
for ( int i=0; i < live.size(); i++ ) {
- DatanodeInfo d = ( DatanodeInfo ) live.elementAt(i);
- generateLiveNodeData( out, d );
+ generateLiveNodeData( out, live.get(i), port_suffix, true );
}
}
out.print("</table>\n");
+
+ counterReset();
- out.print("<br> <a id=\"title\"> " +
+ out.print("<br> <a name=\"DeadNodes\" id=\"title\"> " +
" Dead Datanodes : " +dead.size() + "</a><br><br>\n");
if ( dead.size() > 0 ) {
- out.print( "<table border=\"1\"> <tr id=\"row1\"> " +
+ out.print( "<table border=1 cellspacing=0> <tr id=\"row1\"> " +
"<td> Node \n" );
for ( int i=0; i < dead.size() ; i++ ) {
- DatanodeInfo d = ( DatanodeInfo ) dead.elementAt(i);
- out.print( "<tr> <td> " + d.getName() + "\n" );
+ generateLiveNodeData( out, dead.get(i), port_suffix, false );
}
out.print("</table>\n");
Modified: lucene/hadoop/trunk/src/webapps/static/hadoop.css
URL: http://svn.apache.org/viewvc/lucene/hadoop/trunk/src/webapps/static/hadoop.css?view=diff&rev=477850&r1=477849&r2=477850
==============================================================================
--- lucene/hadoop/trunk/src/webapps/static/hadoop.css (original)
+++ lucene/hadoop/trunk/src/webapps/static/hadoop.css Tue Nov 21 11:53:40 2006
@@ -1,8 +1,16 @@
+body {
+ background-color : #ffffff;
+ font-family : sans-serif;
+}
div#dfsnodetable tr#row1, div#dfstable td#col1 {
font-weight : bolder;
}
+div#dfstable td#col3 {
+ text-align : right;
+}
+
div#dfsnodetable caption {
text-align : left;
}
@@ -12,11 +20,35 @@
font-weight : bolder;
}
+div#dfsnodetable td, th {
+ border-bottom-style : none;
+}
+
+div#dfsnodetable th.header, th.headerASC, th.headerDSC {
+ padding-bottom : 4px;
+ padding-top : 4px;
+}
+div#dfsnodetable th.header:hover, th.headerASC:hover, th.headerDSC:hover {
+ text-decoration : underline;
+ cursor : pointer;
+}
+
+div#dfsnodetable td.blocks, td.size, td.pcused, td.lastcontact {
+ text-align : right;
+}
+
+div#dfsnodetable .rowNormal .header {
+ background-color : #ffffff;
+}
+div#dfsnodetable .rowAlt, .headerASC, .headerDSC {
+ background-color : lightyellow;
+}
+
div#dfstable table {
width : 40%;
}
-div#dfsnodetable td, div#dfstable td {
+div#dfsnodetable td, div#dfsnodetable th, div#dfstable td {
padding-left : 10px;
padding-right : 10px;
}