source: proiecte/HadoopJUnit/hadoop-0.20.1/src/test/org/apache/hadoop/hdfs/DataNodeCluster.java @ 120

Last change on this file since 120 was 120, checked in by (none), 14 years ago

Added the mail files for the Hadoop JUNit Project

  • Property svn:executable set to *
File size: 8.8 KB
Line 
1/**
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements.  See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership.  The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License.  You may obtain a copy of the License at
9 *
10 *     http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 */
18package org.apache.hadoop.hdfs;
19
20import java.io.IOException;
21import java.net.UnknownHostException;
22import java.security.NoSuchAlgorithmException;
23import java.security.SecureRandom;
24import java.util.Random;
25
26import org.apache.hadoop.conf.Configuration;
27import org.apache.hadoop.fs.FileSystem;
28import org.apache.hadoop.hdfs.protocol.Block;
29import org.apache.hadoop.hdfs.server.common.HdfsConstants.StartupOption;
30import org.apache.hadoop.hdfs.server.datanode.SimulatedFSDataset;
31import org.apache.hadoop.hdfs.server.namenode.CreateEditsLog;
32import org.apache.hadoop.net.DNS;
33
34
35/**
36 *
37
38 *
39 * This program starts a mini cluster of data nodes
40 *  (ie a mini cluster without the name node), all within one address space.
41 *  It is assumed that the name node has been started separately prior
42 *  to running this program.
43 * 
44 *  A use case of this is to run a real name node with a large number of
45 *  simulated data nodes for say a NN benchmark.
46 * 
47 * Synopisis:
48 *   DataNodeCluster -n numDatNodes [-racks numRacks] -simulated
49 *              [-inject startingBlockId numBlocksPerDN]
50 *              [ -r replicationForInjectedBlocks ]
51 *              [-d editsLogDirectory]
52 *
53 * if -simulated is specified then simulated data nodes are started.
54 * if -inject is specified then blocks are injected in each datanode;
55 *    -inject option is valid only for simulated data nodes.
56 *   
57 *    See Also @link #CreateEditsLog for creating a edits log file to
58 *    inject a matching set of blocks into into a name node.
59 *    Typical use of -inject is to inject blocks into a set of datanodes
60 *    using this DataNodeCLuster command
61 *    and then to inject the same blocks into a name node using the
62 *    CreateEditsLog command.
63 *
64 */
65
66public class DataNodeCluster {
67  static final String DATANODE_DIRS = "/tmp/DataNodeCluster";
68  static String dataNodeDirs = DATANODE_DIRS;
69  static final String USAGE =
70    "Usage: datanodecluster " +
71    " -n <numDataNodes> " + 
72    " [-racks <numRacks>] " +
73    " [-simulated] " +
74    " [-inject startingBlockId numBlocksPerDN]" +
75    " [-r replicationFactorForInjectedBlocks]" +
76    " [-d dataNodeDirs]\n" + 
77    "      Default datanode direcory is " + DATANODE_DIRS + "\n" +
78    "      Default replication factor for injected blocks is 1\n" +
79    "      Defaul rack is used if -racks is not specified\n" +
80    "      Data nodes are simulated if -simulated OR conf file specifies simulated\n";
81 
82 
83  static void printUsageExit() {
84    System.out.println(USAGE);
85    System.exit(-1); 
86  }
87  static void printUsageExit(String err) {
88    System.out.println(err);
89    printUsageExit();
90  }
91 
92  public static void main(String[] args) {
93    int numDataNodes = 0;
94    int numRacks = 0;
95    boolean inject = false;
96    long startingBlockId = 1;
97    int numBlocksPerDNtoInject = 0;
98    int replication = 1;
99   
100    Configuration conf = new Configuration();
101
102    for (int i = 0; i < args.length; i++) { // parse command line
103      if (args[i].equals("-n")) {
104        if (++i >= args.length || args[i].startsWith("-")) {
105          printUsageExit("missing number of nodes");
106        }
107        numDataNodes = Integer.parseInt(args[i]);
108      } else if (args[i].equals("-racks")) {
109        if (++i >= args.length  || args[i].startsWith("-")) {
110          printUsageExit("Missing number of racks");
111        }
112        numRacks = Integer.parseInt(args[i]);
113      } else if (args[i].equals("-r")) {
114        if (++i >= args.length || args[i].startsWith("-")) {
115          printUsageExit("Missing replicaiton factor");
116        }
117        replication = Integer.parseInt(args[i]);
118      } else if (args[i].equals("-d")) {
119        if (++i >= args.length || args[i].startsWith("-")) {
120          printUsageExit("Missing datanode dirs parameter");
121        }
122        dataNodeDirs = args[i];
123      } else if (args[i].equals("-simulated")) {
124        conf.setBoolean(SimulatedFSDataset.CONFIG_PROPERTY_SIMULATED, true);
125      } else if (args[i].equals("-inject")) {
126        if (!conf.getBoolean(SimulatedFSDataset.CONFIG_PROPERTY_SIMULATED,
127                                                                false) ) {
128          System.out.print("-inject is valid only for simulated");
129          printUsageExit(); 
130        }
131       inject = true;
132       if (++i >= args.length  || args[i].startsWith("-")) {
133         printUsageExit(
134             "Missing starting block and number of blocks per DN to inject");
135       }
136       startingBlockId = Integer.parseInt(args[i]);
137       if (++i >= args.length  || args[i].startsWith("-")) {
138         printUsageExit("Missing number of blocks to inject");
139       }
140       numBlocksPerDNtoInject = Integer.parseInt(args[i]);     
141      } else {
142        printUsageExit();
143      }
144    }
145    if (numDataNodes <= 0 || replication <= 0 ) {
146      printUsageExit("numDataNodes and replication have to be greater than zero");
147    }
148    if (replication > numDataNodes) {
149      printUsageExit("Replication must be less than or equal to numDataNodes");
150     
151    }
152    String nameNodeAdr = FileSystem.getDefaultUri(conf).getAuthority();
153    if (nameNodeAdr == null) {
154      System.out.println("No name node address and port in config");
155      System.exit(-1);
156    }
157    boolean simulated = 
158      conf.getBoolean(SimulatedFSDataset.CONFIG_PROPERTY_SIMULATED, false);
159    System.out.println("Starting " + numDataNodes + 
160          (simulated ? " Simulated " : " ") +
161          " Data Nodes that will connect to Name Node at " + nameNodeAdr);
162 
163    System.setProperty("test.build.data", dataNodeDirs);
164
165    MiniDFSCluster mc = new MiniDFSCluster();
166    try {
167      mc.formatDataNodeDirs();
168    } catch (IOException e) {
169      System.out.println("Error formating data node dirs:" + e);
170    }
171
172    String[] rack4DataNode = null;
173    if (numRacks > 0) {
174      System.out.println("Using " + numRacks + " racks: ");
175      String rackPrefix = getUniqueRackPrefix();
176
177      rack4DataNode = new String[numDataNodes];
178      for (int i = 0; i < numDataNodes; ++i ) {
179        //rack4DataNode[i] = racks[i%numRacks];
180        rack4DataNode[i] = rackPrefix + "-" + i%numRacks;
181        System.out.println("Data Node " + i + " using " + rack4DataNode[i]);
182       
183       
184      }
185    }
186    try {
187      mc.startDataNodes(conf, numDataNodes, true, StartupOption.REGULAR,
188          rack4DataNode);
189      if (inject) {
190        long blockSize = 10;
191        System.out.println("Injecting " + numBlocksPerDNtoInject +
192            " blocks in each DN starting at blockId " + startingBlockId +
193            " with blocksize of " + blockSize);
194        Block[] blocks = new Block[numBlocksPerDNtoInject];
195        long blkid = startingBlockId;
196        for (int i_dn = 0; i_dn < numDataNodes; ++i_dn) {
197          for (int i = 0; i < blocks.length; ++i) {
198            blocks[i] = new Block(blkid++, blockSize,
199                CreateEditsLog.BLOCK_GENERATION_STAMP);
200          }
201          for (int i = 1; i <= replication; ++i) { 
202            // inject blocks for dn_i into dn_i and replica in dn_i's neighbors
203            mc.injectBlocks((i_dn + i- 1)% numDataNodes, blocks);
204            System.out.println("Injecting blocks of dn " + i_dn  + " into dn" + 
205                ((i_dn + i- 1)% numDataNodes));
206          }
207        }
208        System.out.println("Created blocks from Bids " 
209            + startingBlockId + " to "  + (blkid -1));
210      }
211
212    } catch (IOException e) {
213      System.out.println("Error creating data node:" + e);
214    } 
215  }
216
217  /*
218   * There is high probability that the rack id generated here will
219   * not conflict with those of other data node cluster.
220   * Not perfect but mostly unique rack ids are good enough
221   */
222  static private String getUniqueRackPrefix() {
223 
224    String ip = "unknownIP";
225    try {
226      ip = DNS.getDefaultIP("default");
227    } catch (UnknownHostException ignored) {
228      System.out.println("Could not find ip address of \"default\" inteface.");
229    }
230   
231    int rand = 0;
232    try {
233      rand = SecureRandom.getInstance("SHA1PRNG").nextInt(Integer.MAX_VALUE);
234    } catch (NoSuchAlgorithmException e) {
235      rand = (new Random()).nextInt(Integer.MAX_VALUE);
236    }
237    return "/Rack-" + rand + "-"+ ip  + "-" + 
238                      System.currentTimeMillis();
239  }
240}
Note: See TracBrowser for help on using the repository browser.