HDFS-10838. Last full block report received time for each DN should be easily discoverable. Contributed by Surendra Singh Lilhore.

This commit is contained in:
Arpit Agarwal 2017-03-06 16:39:53 -08:00
parent 6e75c1e2f0
commit 8dc8ecbb91
10 changed files with 78 additions and 4 deletions

View File

@ -85,6 +85,8 @@ public class DatanodeInfo extends DatanodeID implements Node {
protected AdminStates adminState; protected AdminStates adminState;
private long maintenanceExpireTimeInMS; private long maintenanceExpireTimeInMS;
private long lastBlockReportTime;
private long lastBlockReportMonotonic;
protected DatanodeInfo(DatanodeInfo from) { protected DatanodeInfo(DatanodeInfo from) {
super(from); super(from);
@ -101,6 +103,8 @@ public class DatanodeInfo extends DatanodeID implements Node {
this.location = from.getNetworkLocation(); this.location = from.getNetworkLocation();
this.adminState = from.getAdminState(); this.adminState = from.getAdminState();
this.upgradeDomain = from.getUpgradeDomain(); this.upgradeDomain = from.getUpgradeDomain();
this.lastBlockReportTime = from.getLastBlockReportTime();
this.lastBlockReportMonotonic = from.getLastBlockReportMonotonic();
} }
protected DatanodeInfo(DatanodeID nodeID) { protected DatanodeInfo(DatanodeID nodeID) {
@ -116,6 +120,8 @@ public class DatanodeInfo extends DatanodeID implements Node {
this.lastUpdateMonotonic = 0L; this.lastUpdateMonotonic = 0L;
this.xceiverCount = 0; this.xceiverCount = 0;
this.adminState = null; this.adminState = null;
this.lastBlockReportTime = 0L;
this.lastBlockReportMonotonic = 0L;
} }
protected DatanodeInfo(DatanodeID nodeID, String location) { protected DatanodeInfo(DatanodeID nodeID, String location) {
@ -131,7 +137,8 @@ public class DatanodeInfo extends DatanodeID implements Node {
final long blockPoolUsed, final long cacheCapacity, final long cacheUsed, final long blockPoolUsed, final long cacheCapacity, final long cacheUsed,
final long lastUpdate, final long lastUpdateMonotonic, final long lastUpdate, final long lastUpdateMonotonic,
final int xceiverCount, final String networkLocation, final int xceiverCount, final String networkLocation,
final AdminStates adminState, final String upgradeDomain) { final AdminStates adminState, final String upgradeDomain,
final long lastBlockReportTime, final long lastBlockReportMonotonic) {
super(ipAddr, hostName, datanodeUuid, xferPort, infoPort, infoSecurePort, super(ipAddr, hostName, datanodeUuid, xferPort, infoPort, infoSecurePort,
ipcPort); ipcPort);
this.capacity = capacity; this.capacity = capacity;
@ -147,6 +154,8 @@ public class DatanodeInfo extends DatanodeID implements Node {
this.location = networkLocation; this.location = networkLocation;
this.adminState = adminState; this.adminState = adminState;
this.upgradeDomain = upgradeDomain; this.upgradeDomain = upgradeDomain;
this.lastBlockReportTime = lastBlockReportTime;
this.lastBlockReportMonotonic = lastBlockReportMonotonic;
} }
/** Network location name. */ /** Network location name. */
@ -391,6 +400,11 @@ public class DatanodeInfo extends DatanodeID implements Node {
.append(percent2String(cacheRemainingPercent)).append("\n"); .append(percent2String(cacheRemainingPercent)).append("\n");
buffer.append("Xceivers: ").append(getXceiverCount()).append("\n"); buffer.append("Xceivers: ").append(getXceiverCount()).append("\n");
buffer.append("Last contact: ").append(new Date(lastUpdate)).append("\n"); buffer.append("Last contact: ").append(new Date(lastUpdate)).append("\n");
buffer
.append("Last Block Report: ")
.append(
lastBlockReportTime != 0 ? new Date(lastBlockReportTime) : "Never")
.append("\n");
return buffer.toString(); return buffer.toString();
} }
@ -503,6 +517,26 @@ public class DatanodeInfo extends DatanodeID implements Node {
return this.maintenanceExpireTimeInMS; return this.maintenanceExpireTimeInMS;
} }
/** Sets the last block report time. */
public void setLastBlockReportTime(long lastBlockReportTime) {
this.lastBlockReportTime = lastBlockReportTime;
}
/** Sets the last block report monotonic time. */
public void setLastBlockReportMonotonic(long lastBlockReportMonotonic) {
this.lastBlockReportMonotonic = lastBlockReportMonotonic;
}
/** Last block report time. */
public long getLastBlockReportTime() {
return lastBlockReportTime;
}
/** Last block report monotonic time. */
public long getLastBlockReportMonotonic() {
return lastBlockReportMonotonic;
}
/** /**
* Take the node out of maintenance mode. * Take the node out of maintenance mode.
*/ */
@ -643,6 +677,8 @@ public class DatanodeInfo extends DatanodeID implements Node {
private int infoSecurePort; private int infoSecurePort;
private int ipcPort; private int ipcPort;
private long nonDfsUsed = 0L; private long nonDfsUsed = 0L;
private long lastBlockReportTime = 0L;
private long lastBlockReportMonotonic = 0L;
public DatanodeInfoBuilder setFrom(DatanodeInfo from) { public DatanodeInfoBuilder setFrom(DatanodeInfo from) {
this.capacity = from.getCapacity(); this.capacity = from.getCapacity();
@ -658,6 +694,8 @@ public class DatanodeInfo extends DatanodeID implements Node {
this.location = from.getNetworkLocation(); this.location = from.getNetworkLocation();
this.adminState = from.getAdminState(); this.adminState = from.getAdminState();
this.upgradeDomain = from.getUpgradeDomain(); this.upgradeDomain = from.getUpgradeDomain();
this.lastBlockReportTime = from.getLastBlockReportTime();
this.lastBlockReportMonotonic = from.getLastBlockReportMonotonic();
setNodeID(from); setNodeID(from);
return this; return this;
} }
@ -775,12 +813,22 @@ public class DatanodeInfo extends DatanodeID implements Node {
return this; return this;
} }
public DatanodeInfoBuilder setLastBlockReportTime(long time) {
this.lastBlockReportTime = time;
return this;
}
public DatanodeInfoBuilder setLastBlockReportMonotonic(long time) {
this.lastBlockReportMonotonic = time;
return this;
}
public DatanodeInfo build() { public DatanodeInfo build() {
return new DatanodeInfo(ipAddr, hostName, datanodeUuid, xferPort, return new DatanodeInfo(ipAddr, hostName, datanodeUuid, xferPort,
infoPort, infoSecurePort, ipcPort, capacity, dfsUsed, nonDfsUsed, infoPort, infoSecurePort, ipcPort, capacity, dfsUsed, nonDfsUsed,
remaining, blockPoolUsed, cacheCapacity, cacheUsed, lastUpdate, remaining, blockPoolUsed, cacheCapacity, cacheUsed, lastUpdate,
lastUpdateMonotonic, xceiverCount, location, adminState, lastUpdateMonotonic, xceiverCount, location, adminState,
upgradeDomain); upgradeDomain, lastBlockReportTime, lastBlockReportMonotonic);
} }
} }
} }

View File

@ -294,6 +294,8 @@ public class PBHelperClient {
.setLastUpdateMonotonic(info.getLastUpdateMonotonic()) .setLastUpdateMonotonic(info.getLastUpdateMonotonic())
.setXceiverCount(info.getXceiverCount()) .setXceiverCount(info.getXceiverCount())
.setAdminState(convert(info.getAdminState())) .setAdminState(convert(info.getAdminState()))
.setLastBlockReportTime(info.getLastBlockReportTime())
.setLastBlockReportMonotonic(info.getLastBlockReportMonotonic())
.build(); .build();
return builder.build(); return builder.build();
} }
@ -563,7 +565,11 @@ public class PBHelperClient {
.setLastUpdateMonotonic(di.getLastUpdateMonotonic()) .setLastUpdateMonotonic(di.getLastUpdateMonotonic())
.setXceiverCount(di.getXceiverCount()) .setXceiverCount(di.getXceiverCount())
.setAdminState(convert(di.getAdminState())).setUpgradeDomain( .setAdminState(convert(di.getAdminState())).setUpgradeDomain(
di.hasUpgradeDomain() ? di.getUpgradeDomain() : null); di.hasUpgradeDomain() ? di.getUpgradeDomain() : null)
.setLastBlockReportTime(di.hasLastBlockReportTime() ?
di.getLastBlockReportTime() : 0)
.setLastBlockReportMonotonic(di.hasLastBlockReportMonotonic() ?
di.getLastBlockReportMonotonic() : 0);
if (di.hasNonDfsUsed()) { if (di.hasNonDfsUsed()) {
dinfo.setNonDfsUsed(di.getNonDfsUsed()); dinfo.setNonDfsUsed(di.getNonDfsUsed());
} else { } else {

View File

@ -295,6 +295,8 @@ class JsonUtilClient {
DatanodeInfo.AdminStates DatanodeInfo.AdminStates
.valueOf(getString(m, "adminState", "NORMAL"))) .valueOf(getString(m, "adminState", "NORMAL")))
.setUpgradeDomain(getString(m, "upgradeDomain", "")) .setUpgradeDomain(getString(m, "upgradeDomain", ""))
.setLastBlockReportTime(getLong(m, "lastBlockReportTime", 0L))
.setLastBlockReportMonotonic(getLong(m, "lastBlockReportMonotonic", 0L))
.build(); .build();
} }

View File

@ -102,6 +102,8 @@ message DatanodeInfoProto {
optional uint64 cacheUsed = 12 [default = 0]; optional uint64 cacheUsed = 12 [default = 0];
optional uint64 lastUpdateMonotonic = 13 [default = 0]; optional uint64 lastUpdateMonotonic = 13 [default = 0];
optional string upgradeDomain = 14; optional string upgradeDomain = 14;
optional uint64 lastBlockReportTime = 15 [default = 0];
optional uint64 lastBlockReportMonotonic = 16 [default = 0];
} }
/** /**

View File

@ -18,6 +18,7 @@
package org.apache.hadoop.hdfs.server.blockmanagement; package org.apache.hadoop.hdfs.server.blockmanagement;
import static org.apache.hadoop.util.ExitUtil.terminate; import static org.apache.hadoop.util.ExitUtil.terminate;
import static org.apache.hadoop.util.Time.now;
import java.io.IOException; import java.io.IOException;
import java.io.PrintWriter; import java.io.PrintWriter;
@ -2158,6 +2159,8 @@ public class BlockManager implements BlockStatsMXBean {
long leaseId = this.getBlockReportLeaseManager().removeLease(node); long leaseId = this.getBlockReportLeaseManager().removeLease(node);
BlockManagerFaultInjector.getInstance(). BlockManagerFaultInjector.getInstance().
removeBlockReportLease(node, leaseId); removeBlockReportLease(node, leaseId);
node.setLastBlockReportTime(now());
node.setLastBlockReportMonotonic(Time.monotonicNow());
} }
LOG.debug("Processing RPC with index {} out of total {} RPCs in " LOG.debug("Processing RPC with index {} out of total {} RPCs in "
+ "processReport 0x{}", context.getCurRpc(), + "processReport 0x{}", context.getCurRpc(),

View File

@ -5445,7 +5445,9 @@ public class FSNamesystem implements Namesystem, FSNamesystemMBean,
.put("blockScheduled", node.getBlocksScheduled()) .put("blockScheduled", node.getBlocksScheduled())
.put("blockPoolUsed", node.getBlockPoolUsed()) .put("blockPoolUsed", node.getBlockPoolUsed())
.put("blockPoolUsedPercent", node.getBlockPoolUsedPercent()) .put("blockPoolUsedPercent", node.getBlockPoolUsedPercent())
.put("volfails", node.getVolumeFailures()); .put("volfails", node.getVolumeFailures())
// Block report time in minutes
.put("lastBlockReport", getLastBlockReport(node));
VolumeFailureSummary volumeFailureSummary = node.getVolumeFailureSummary(); VolumeFailureSummary volumeFailureSummary = node.getVolumeFailureSummary();
if (volumeFailureSummary != null) { if (volumeFailureSummary != null) {
innerinfo innerinfo
@ -5544,6 +5546,10 @@ public class FSNamesystem implements Namesystem, FSNamesystemMBean,
return (monotonicNow() - alivenode.getLastUpdateMonotonic())/1000; return (monotonicNow() - alivenode.getLastUpdateMonotonic())/1000;
} }
private Object getLastBlockReport(DatanodeDescriptor node) {
return (monotonicNow() - node.getLastBlockReportMonotonic()) / 60000;
}
private long getDfsUsed(DatanodeDescriptor alivenode) { private long getDfsUsed(DatanodeDescriptor alivenode) {
return alivenode.getDfsUsed(); return alivenode.getDfsUsed();
} }

View File

@ -181,6 +181,9 @@ public class JsonUtil {
if (datanodeinfo.getUpgradeDomain() != null) { if (datanodeinfo.getUpgradeDomain() != null) {
m.put("upgradeDomain", datanodeinfo.getUpgradeDomain()); m.put("upgradeDomain", datanodeinfo.getUpgradeDomain());
} }
m.put("lastBlockReportTime", datanodeinfo.getLastBlockReportTime());
m.put("lastBlockReportMonotonic",
datanodeinfo.getLastBlockReportMonotonic());
return m; return m;
} }

View File

@ -309,6 +309,7 @@
<th>Node</th> <th>Node</th>
<th>Http Address</th> <th>Http Address</th>
<th>Last contact</th> <th>Last contact</th>
<th>Last Block Report</th>
<th style="width:180px; text-align:center">Capacity</th> <th style="width:180px; text-align:center">Capacity</th>
<th>Blocks</th> <th>Blocks</th>
<th>Block pool used</th> <th>Block pool used</th>
@ -320,6 +321,7 @@
<td ng-value="{state}-{name}" class="dfshealth-node-icon dfshealth-node-{state}">{name} ({xferaddr})</td> <td ng-value="{state}-{name}" class="dfshealth-node-icon dfshealth-node-{state}">{name} ({xferaddr})</td>
<td ng-value="{state}-{name}"><a href='//{dnWebAddress}'>{dnWebAddress}</a></td> <td ng-value="{state}-{name}"><a href='//{dnWebAddress}'>{dnWebAddress}</a></td>
<td ng-value="{lastContact}">{lastContact}s</td> <td ng-value="{lastContact}">{lastContact}s</td>
<td ng-value="{lastBlockReport}">{lastBlockReport}m</td>
<td ng-value="{usedPercentage}"> <td ng-value="{usedPercentage}">
<div> <div>
<div style="display:inline-block; float: left; padding-right: 10px;">{capacity|fmt_bytes}</div> <div style="display:inline-block; float: left; padding-right: 10px;">{capacity|fmt_bytes}</div>

View File

@ -333,6 +333,7 @@
{ 'orderDataType': 'ng-value', 'searchable': true }, { 'orderDataType': 'ng-value', 'searchable': true },
{ 'orderDataType': 'ng-value', 'type': 'numeric' }, { 'orderDataType': 'ng-value', 'type': 'numeric' },
{ 'orderDataType': 'ng-value', 'type': 'numeric' }, { 'orderDataType': 'ng-value', 'type': 'numeric' },
{ 'orderDataType': 'ng-value', 'type': 'numeric' },
{ 'orderData': 3, 'type': 'numeric' }, { 'orderData': 3, 'type': 'numeric' },
{ 'orderDataType': 'ng-value', 'type': 'numeric'}, { 'orderDataType': 'ng-value', 'type': 'numeric'},
{ 'orderData': 5 } { 'orderData': 5 }

View File

@ -161,6 +161,7 @@ public class TestNameNodeMXBean {
assertTrue(((Long)liveNode.get("capacity")) > 0); assertTrue(((Long)liveNode.get("capacity")) > 0);
assertTrue(liveNode.containsKey("numBlocks")); assertTrue(liveNode.containsKey("numBlocks"));
assertTrue(((Long)liveNode.get("numBlocks")) == 0); assertTrue(((Long)liveNode.get("numBlocks")) == 0);
assertTrue(liveNode.containsKey("lastBlockReport"));
// a. By default the upgrade domain isn't defined on any DN. // a. By default the upgrade domain isn't defined on any DN.
// b. If the upgrade domain is set on a DN, JMX should have the same // b. If the upgrade domain is set on a DN, JMX should have the same
// value. // value.