1 | package org.apache.hadoop.hdfs.server.namenode; |
---|
2 | |
---|
3 | import java.util.Collection; |
---|
4 | import java.util.Iterator; |
---|
5 | |
---|
6 | import org.apache.hadoop.conf.Configuration; |
---|
7 | import org.apache.hadoop.fs.FileSystem; |
---|
8 | import org.apache.hadoop.fs.Path; |
---|
9 | import org.apache.hadoop.hdfs.DFSTestUtil; |
---|
10 | import org.apache.hadoop.hdfs.MiniDFSCluster; |
---|
11 | import org.apache.hadoop.hdfs.MiniDFSCluster.DataNodeProperties; |
---|
12 | import org.apache.hadoop.hdfs.protocol.Block; |
---|
13 | import org.apache.hadoop.hdfs.server.namenode.FSNamesystem.NumberReplicas; |
---|
14 | |
---|
15 | import junit.framework.TestCase; |
---|
16 | |
---|
17 | /** |
---|
18 | * Test if live nodes count per node is correct |
---|
19 | * so NN makes right decision for under/over-replicated blocks |
---|
20 | */ |
---|
21 | public class TestNodeCount extends TestCase { |
---|
22 | public void testNodeCount() throws Exception { |
---|
23 | // start a mini dfs cluster of 2 nodes |
---|
24 | final Configuration conf = new Configuration(); |
---|
25 | final short REPLICATION_FACTOR = (short)2; |
---|
26 | final MiniDFSCluster cluster = |
---|
27 | new MiniDFSCluster(conf, REPLICATION_FACTOR, true, null); |
---|
28 | try { |
---|
29 | final FSNamesystem namesystem = cluster.getNameNode().namesystem; |
---|
30 | final FileSystem fs = cluster.getFileSystem(); |
---|
31 | |
---|
32 | // populate the cluster with a one block file |
---|
33 | final Path FILE_PATH = new Path("/testfile"); |
---|
34 | DFSTestUtil.createFile(fs, FILE_PATH, 1L, REPLICATION_FACTOR, 1L); |
---|
35 | DFSTestUtil.waitReplication(fs, FILE_PATH, REPLICATION_FACTOR); |
---|
36 | Block block = DFSTestUtil.getFirstBlock(fs, FILE_PATH); |
---|
37 | |
---|
38 | // keep a copy of all datanode descriptor |
---|
39 | DatanodeDescriptor[] datanodes = (DatanodeDescriptor[]) |
---|
40 | namesystem.heartbeats.toArray(new DatanodeDescriptor[REPLICATION_FACTOR]); |
---|
41 | |
---|
42 | // start two new nodes |
---|
43 | cluster.startDataNodes(conf, 2, true, null, null); |
---|
44 | cluster.waitActive(); |
---|
45 | |
---|
46 | // bring down first datanode |
---|
47 | DatanodeDescriptor datanode = datanodes[0]; |
---|
48 | DataNodeProperties dnprop = cluster.stopDataNode(datanode.getName()); |
---|
49 | // make sure that NN detects that the datanode is down |
---|
50 | synchronized (namesystem.heartbeats) { |
---|
51 | datanode.setLastUpdate(0); // mark it dead |
---|
52 | namesystem.heartbeatCheck(); |
---|
53 | } |
---|
54 | // the block will be replicated |
---|
55 | DFSTestUtil.waitReplication(fs, FILE_PATH, REPLICATION_FACTOR); |
---|
56 | |
---|
57 | // restart the first datanode |
---|
58 | cluster.restartDataNode(dnprop); |
---|
59 | cluster.waitActive(); |
---|
60 | |
---|
61 | // check if excessive replica is detected |
---|
62 | NumberReplicas num = null; |
---|
63 | do { |
---|
64 | synchronized (namesystem) { |
---|
65 | num = namesystem.countNodes(block); |
---|
66 | } |
---|
67 | } while (num.excessReplicas() == 0); |
---|
68 | |
---|
69 | // find out a non-excess node |
---|
70 | Iterator<DatanodeDescriptor> iter = namesystem.blocksMap.nodeIterator(block); |
---|
71 | DatanodeDescriptor nonExcessDN = null; |
---|
72 | while (iter.hasNext()) { |
---|
73 | DatanodeDescriptor dn = iter.next(); |
---|
74 | Collection<Block> blocks = namesystem.excessReplicateMap.get(dn.getStorageID()); |
---|
75 | if (blocks == null || !blocks.contains(block) ) { |
---|
76 | nonExcessDN = dn; |
---|
77 | break; |
---|
78 | } |
---|
79 | } |
---|
80 | assertTrue(nonExcessDN!=null); |
---|
81 | |
---|
82 | // bring down non excessive datanode |
---|
83 | dnprop = cluster.stopDataNode(nonExcessDN.getName()); |
---|
84 | // make sure that NN detects that the datanode is down |
---|
85 | synchronized (namesystem.heartbeats) { |
---|
86 | nonExcessDN.setLastUpdate(0); // mark it dead |
---|
87 | namesystem.heartbeatCheck(); |
---|
88 | } |
---|
89 | |
---|
90 | // The block should be replicated |
---|
91 | do { |
---|
92 | num = namesystem.countNodes(block); |
---|
93 | } while (num.liveReplicas() != REPLICATION_FACTOR); |
---|
94 | |
---|
95 | // restart the first datanode |
---|
96 | cluster.restartDataNode(dnprop); |
---|
97 | cluster.waitActive(); |
---|
98 | |
---|
99 | // check if excessive replica is detected |
---|
100 | do { |
---|
101 | num = namesystem.countNodes(block); |
---|
102 | } while (num.excessReplicas() == 2); |
---|
103 | } finally { |
---|
104 | cluster.shutdown(); |
---|
105 | } |
---|
106 | } |
---|
107 | } |
---|