HDFS-9034. StorageTypeStats Metric should not count failed storage. Contributed by Surendra Singh Lilhore.
(cherry picked from commit df83230948
)
This commit is contained in:
parent
131260f0a7
commit
0d249a5e28
|
@ -953,6 +953,7 @@ public class DatanodeManager {
|
||||||
// no need to update its timestamp
|
// no need to update its timestamp
|
||||||
// because its is done when the descriptor is created
|
// because its is done when the descriptor is created
|
||||||
heartbeatManager.addDatanode(nodeDescr);
|
heartbeatManager.addDatanode(nodeDescr);
|
||||||
|
heartbeatManager.updateDnStat(nodeDescr);
|
||||||
incrementVersionCount(nodeReg.getSoftwareVersion());
|
incrementVersionCount(nodeReg.getSoftwareVersion());
|
||||||
startDecommissioningIfExcluded(nodeDescr);
|
startDecommissioningIfExcluded(nodeDescr);
|
||||||
success = true;
|
success = true;
|
||||||
|
|
|
@ -19,6 +19,7 @@ package org.apache.hadoop.hdfs.server.blockmanagement;
|
||||||
|
|
||||||
import org.apache.hadoop.fs.StorageType;
|
import org.apache.hadoop.fs.StorageType;
|
||||||
import org.apache.hadoop.hdfs.DFSUtilClient;
|
import org.apache.hadoop.hdfs.DFSUtilClient;
|
||||||
|
import org.apache.hadoop.hdfs.server.protocol.DatanodeStorage;
|
||||||
|
|
||||||
import java.util.EnumMap;
|
import java.util.EnumMap;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
|
@ -61,8 +62,10 @@ class DatanodeStats {
|
||||||
}
|
}
|
||||||
Set<StorageType> storageTypes = new HashSet<>();
|
Set<StorageType> storageTypes = new HashSet<>();
|
||||||
for (DatanodeStorageInfo storageInfo : node.getStorageInfos()) {
|
for (DatanodeStorageInfo storageInfo : node.getStorageInfos()) {
|
||||||
statsMap.addStorage(storageInfo, node);
|
if (storageInfo.getState() != DatanodeStorage.State.FAILED) {
|
||||||
storageTypes.add(storageInfo.getStorageType());
|
statsMap.addStorage(storageInfo, node);
|
||||||
|
storageTypes.add(storageInfo.getStorageType());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
for (StorageType storageType : storageTypes) {
|
for (StorageType storageType : storageTypes) {
|
||||||
statsMap.addNode(storageType, node);
|
statsMap.addNode(storageType, node);
|
||||||
|
@ -86,8 +89,10 @@ class DatanodeStats {
|
||||||
}
|
}
|
||||||
Set<StorageType> storageTypes = new HashSet<>();
|
Set<StorageType> storageTypes = new HashSet<>();
|
||||||
for (DatanodeStorageInfo storageInfo : node.getStorageInfos()) {
|
for (DatanodeStorageInfo storageInfo : node.getStorageInfos()) {
|
||||||
statsMap.subtractStorage(storageInfo, node);
|
if (storageInfo.getState() != DatanodeStorage.State.FAILED) {
|
||||||
storageTypes.add(storageInfo.getStorageType());
|
statsMap.subtractStorage(storageInfo, node);
|
||||||
|
storageTypes.add(storageInfo.getStorageType());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
for (StorageType storageType : storageTypes) {
|
for (StorageType storageType : storageTypes) {
|
||||||
statsMap.subtractNode(storageType, node);
|
statsMap.subtractNode(storageType, node);
|
||||||
|
@ -202,10 +207,12 @@ class DatanodeStats {
|
||||||
|
|
||||||
private void subtractNode(StorageType storageType,
|
private void subtractNode(StorageType storageType,
|
||||||
final DatanodeDescriptor node) {
|
final DatanodeDescriptor node) {
|
||||||
StorageTypeStats storageTypeStats =
|
StorageTypeStats storageTypeStats = storageTypeStatsMap.get(storageType);
|
||||||
storageTypeStatsMap.get(storageType);
|
|
||||||
if (storageTypeStats != null) {
|
if (storageTypeStats != null) {
|
||||||
storageTypeStats.subtractNode(node);
|
storageTypeStats.subtractNode(node);
|
||||||
|
if (storageTypeStats.getNodesInService() == 0) {
|
||||||
|
storageTypeStatsMap.remove(storageType);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -203,6 +203,7 @@ class HeartbeatManager implements DatanodeStatistics {
|
||||||
|
|
||||||
//update its timestamp
|
//update its timestamp
|
||||||
d.updateHeartbeatState(StorageReport.EMPTY_ARRAY, 0L, 0L, 0, 0, null);
|
d.updateHeartbeatState(StorageReport.EMPTY_ARRAY, 0L, 0L, 0, 0, null);
|
||||||
|
stats.add(d);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -212,11 +213,14 @@ class HeartbeatManager implements DatanodeStatistics {
|
||||||
|
|
||||||
synchronized void addDatanode(final DatanodeDescriptor d) {
|
synchronized void addDatanode(final DatanodeDescriptor d) {
|
||||||
// update in-service node count
|
// update in-service node count
|
||||||
stats.add(d);
|
|
||||||
datanodes.add(d);
|
datanodes.add(d);
|
||||||
d.setAlive(true);
|
d.setAlive(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void updateDnStat(final DatanodeDescriptor d){
|
||||||
|
stats.add(d);
|
||||||
|
}
|
||||||
|
|
||||||
synchronized void removeDatanode(DatanodeDescriptor node) {
|
synchronized void removeDatanode(DatanodeDescriptor node) {
|
||||||
if (node.isAlive()) {
|
if (node.isAlive()) {
|
||||||
stats.subtract(node);
|
stats.subtract(node);
|
||||||
|
|
|
@ -18,10 +18,12 @@
|
||||||
package org.apache.hadoop.hdfs.server.blockmanagement;
|
package org.apache.hadoop.hdfs.server.blockmanagement;
|
||||||
|
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.junit.Assert.assertFalse;
|
||||||
import static org.junit.Assert.assertNotNull;
|
import static org.junit.Assert.assertNotNull;
|
||||||
import static org.junit.Assert.assertTrue;
|
import static org.junit.Assert.assertTrue;
|
||||||
import static org.junit.Assert.fail;
|
import static org.junit.Assert.fail;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
|
@ -29,9 +31,12 @@ import java.util.HashSet;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
|
import org.apache.hadoop.fs.Path;
|
||||||
import org.apache.hadoop.fs.StorageType;
|
import org.apache.hadoop.fs.StorageType;
|
||||||
|
import org.apache.hadoop.hdfs.DFSTestUtil;
|
||||||
import org.apache.hadoop.hdfs.HdfsConfiguration;
|
import org.apache.hadoop.hdfs.HdfsConfiguration;
|
||||||
import org.apache.hadoop.hdfs.MiniDFSCluster;
|
import org.apache.hadoop.hdfs.MiniDFSCluster;
|
||||||
|
import org.apache.hadoop.hdfs.server.datanode.DataNodeTestUtils;
|
||||||
import org.junit.After;
|
import org.junit.After;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
@ -143,4 +148,61 @@ public class TestBlockStatsMXBean {
|
||||||
assertTrue(typesPresent.contains("DISK"));
|
assertTrue(typesPresent.contains("DISK"));
|
||||||
assertTrue(typesPresent.contains("RAM_DISK"));
|
assertTrue(typesPresent.contains("RAM_DISK"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testStorageTypeStatsWhenStorageFailed() throws Exception {
|
||||||
|
DFSTestUtil.createFile(cluster.getFileSystem(),
|
||||||
|
new Path("/blockStatsFile1"), 1024, (short) 1, 0L);
|
||||||
|
Map<StorageType, StorageTypeStats> storageTypeStatsMap = cluster
|
||||||
|
.getNamesystem().getBlockManager().getStorageTypeStats();
|
||||||
|
|
||||||
|
StorageTypeStats storageTypeStats = storageTypeStatsMap
|
||||||
|
.get(StorageType.RAM_DISK);
|
||||||
|
assertEquals(6, storageTypeStats.getNodesInService());
|
||||||
|
|
||||||
|
storageTypeStats = storageTypeStatsMap.get(StorageType.DISK);
|
||||||
|
assertEquals(3, storageTypeStats.getNodesInService());
|
||||||
|
|
||||||
|
storageTypeStats = storageTypeStatsMap.get(StorageType.ARCHIVE);
|
||||||
|
assertEquals(3, storageTypeStats.getNodesInService());
|
||||||
|
String dataDir = cluster.getDataDirectory();
|
||||||
|
File dn1ArcVol1 = new File(dataDir, "data" + (3 * 0 + 2));
|
||||||
|
File dn2ArcVol1 = new File(dataDir, "data" + (3 * 1 + 2));
|
||||||
|
File dn3ArcVol1 = new File(dataDir, "data" + (3 * 2 + 2));
|
||||||
|
DataNodeTestUtils.injectDataDirFailure(dn1ArcVol1);
|
||||||
|
DataNodeTestUtils.injectDataDirFailure(dn2ArcVol1);
|
||||||
|
DataNodeTestUtils.injectDataDirFailure(dn3ArcVol1);
|
||||||
|
try {
|
||||||
|
DFSTestUtil.createFile(cluster.getFileSystem(), new Path(
|
||||||
|
"/blockStatsFile2"), 1024, (short) 1, 0L);
|
||||||
|
fail("Should throw exception, becuase no DISK storage available");
|
||||||
|
} catch (Exception e) {
|
||||||
|
assertTrue(e.getMessage().contains(
|
||||||
|
"could only be replicated to 0 nodes instead"));
|
||||||
|
}
|
||||||
|
// wait for heartbeat
|
||||||
|
Thread.sleep(6000);
|
||||||
|
storageTypeStatsMap = cluster.getNamesystem().getBlockManager()
|
||||||
|
.getStorageTypeStats();
|
||||||
|
assertFalse("StorageTypeStatsMap should not contain DISK Storage type",
|
||||||
|
storageTypeStatsMap.containsKey(StorageType.DISK));
|
||||||
|
DataNodeTestUtils.restoreDataDirFromFailure(dn1ArcVol1);
|
||||||
|
DataNodeTestUtils.restoreDataDirFromFailure(dn2ArcVol1);
|
||||||
|
DataNodeTestUtils.restoreDataDirFromFailure(dn3ArcVol1);
|
||||||
|
for (int i = 0; i < 3; i++) {
|
||||||
|
cluster.restartDataNode(0, true);
|
||||||
|
}
|
||||||
|
// wait for heartbeat
|
||||||
|
Thread.sleep(6000);
|
||||||
|
storageTypeStatsMap = cluster.getNamesystem().getBlockManager()
|
||||||
|
.getStorageTypeStats();
|
||||||
|
storageTypeStats = storageTypeStatsMap.get(StorageType.RAM_DISK);
|
||||||
|
assertEquals(6, storageTypeStats.getNodesInService());
|
||||||
|
|
||||||
|
storageTypeStats = storageTypeStatsMap.get(StorageType.DISK);
|
||||||
|
assertEquals(3, storageTypeStats.getNodesInService());
|
||||||
|
|
||||||
|
storageTypeStats = storageTypeStatsMap.get(StorageType.ARCHIVE);
|
||||||
|
assertEquals(3, storageTypeStats.getNodesInService());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue