接下来会是几个类的学习
首先是org.apache.hadoop.util.Tool接口
ToolBase类实现了 Tool接口
FsShell 继承了ToolBase类
/**
* A tool interface that support generic options handling
*
* @author hairong
*
*/
// 一个支持通用选项处理的工具界面的接口(执行给予了参数的命令)
public interface Tool extends Configurable {
/**
* execute the command with the given arguments
* @param args command specific arguments
* @return exit code
* @throws Exception
*/
int run( String [] args ) throws Exception;
}
// 典型命令行操作格式
——————————————————————————————————————————————————
public abstract class ToolBase implements Tool
// 抽象类,继承使用
private static final Log LOG = LogFactory.getLog(
"org.apache.hadoop.util.ToolBase");
public Configuration conf;
// 下面两个方法是Configurable接口中的方法
public void setConf(Configuration conf) {
this.conf = conf;
}
public Configuration getConf() {
return conf;
}
/*
* Specify properties of each generic option
*/
static private Options buildGeneralOptions() {
Option fs = OptionBuilder.withArgName("local|namenode:port")
.hasArg()
.withDescription("specify a namenode")
.create("fs");
Option jt = OptionBuilder.withArgName("local|jobtracker:port")
.hasArg()
.withDescription("specify a job tracker")
.create("jt");
Option oconf = OptionBuilder.withArgName("configuration file")
.hasArg()
.withDescription("specify an application configuration file" )
.create("conf");
Option property = OptionBuilder.withArgName("property=value")
.hasArgs()
.withArgPattern("=", 1)
.withDescription("use value for given property")
.create('D');
Options opts = new Options();
opts.addOption(fs);
opts.addOption(jt);
opts.addOption(oconf);
opts.addOption(property);
return opts;
}
/*
* Modify configuration according user-specified generic options
* @param conf Configuration to be modified
* @param line User-specified generic options
*/
static private void processGeneralOptions( Configuration conf,
CommandLine line ) {
if(line.hasOption("fs")) {
conf.set("fs.default.name", line.getOptionValue("fs"));
}
if(line.hasOption("jt")) {
conf.set("mapred.job.tracker", line.getOptionValue("jt"));
}
if(line.hasOption("conf")) {
conf.addFinalResource(new Path(line.getOptionValue("conf")));
}
if(line.hasOption('D')) {
String[] property = line.getOptionValues('D');
for(int i=0; i<property.length-1; i=i+2) {
if(property[i]!=null)
conf.set(property[i], property[i+1]);
}
}
}
/**
* Parse the user-specified options, get the generic options, and modify
* configuration accordingly
* @param conf Configuration to be modified
* @param args User-specified arguments
* @return Commoand-specific arguments
*/
static private String[] parseGeneralOptions( Configuration conf,
String[] args ) {
Options opts = buildGeneralOptions();
CommandLineParser parser = new GnuParser();
try {
CommandLine line = parser.parse( opts, args, true );
processGeneralOptions( conf, line );
return line.getArgs();
} catch(ParseException e) {
LOG.warn("options parsing failed: "+e.getMessage());
HelpFormatter formatter = new HelpFormatter();
formatter.printHelp("general options are: ", opts);
}
return args;
}
/**
* Work as a main program: execute a command and handle exception if any
* @param conf Application default configuration
* @param args User-specified arguments
* @throws Exception
* @return exit code to be passed to a caller. General contract is that code
* equal zero signifies a normal return, negative values signify errors, and
* positive non-zero values can be used to return application-specific codes.
*/
public final int doMain(Configuration conf, String[] args) throws Exception {
String [] commandOptions = parseGeneralOptions(conf, args);
setConf(conf);
return this.run(commandOptions);
}
_____________________________________________________________________________________________
public class DFSAdmin extends FsShell
/**
* Construct a DFSAdmin object.
*/
public DFSAdmin() {
super();
}
/**
* Gives a report on how the FileSystem is doing.
* @exception IOException if the filesystem does not exist.
*/
public void report() throws IOException {
if (fs instanceof DistributedFileSystem) {
DistributedFileSystem dfs = (DistributedFileSystem) fs;
long raw = dfs.getRawCapacity();
long rawUsed = dfs.getRawUsed();
long used = dfs.getUsed();
boolean mode = dfs.setSafeMode(
FSConstants.SafeModeAction.SAFEMODE_GET);
if (mode) {
System.out.println("Safe mode is ON");
}
System.out.println("Total raw bytes: " + raw
+ " (" + byteDesc(raw) + ")");
System.out.println("Used raw bytes: " + rawUsed
+ " (" + byteDesc(rawUsed) + ")");
System.out.println("% used: "
+ limitDecimal(((1.0 * rawUsed) / raw) * 100, 2)
+ "%");
System.out.println();
System.out.println("Total effective bytes: " + used
+ " (" + byteDesc(used) + ")");
System.out.println("Effective replication multiplier: "
+ (1.0 * rawUsed / used));
System.out.println("-------------------------------------------------");
DatanodeInfo[] info = dfs.getDataNodeStats();
System.out.println("Datanodes available: " + info.length);
System.out.println();
for (int i = 0; i < info.length; i++) {
System.out.println(info[i].getDatanodeReport());
System.out.println();
}
}
}
/**
* Safe mode maintenance command.
* Usage: java DFSAdmin -safemode [enter | leave | get]
* @param argv List of of command line parameters.
* @param idx The index of the command that is being processed.
* @exception IOException if the filesystem does not exist.
*/
public void setSafeMode(String[] argv, int idx) throws IOException {
if (!(fs instanceof DistributedFileSystem)) {
System.out.println("FileSystem is " + fs.getName());
return;
}
if (idx != argv.length - 1) {
printUsage("-safemode");
return;
}
FSConstants.SafeModeAction action;
Boolean waitExitSafe = false;
if ("leave".equalsIgnoreCase(argv[idx])) {
action = FSConstants.SafeModeAction.SAFEMODE_LEAVE;
} else if ("enter".equalsIgnoreCase(argv[idx])) {
action = FSConstants.SafeModeAction.SAFEMODE_ENTER;
} else if ("get".equalsIgnoreCase(argv[idx])) {
action = FSConstants.SafeModeAction.SAFEMODE_GET;
} else if ("wait".equalsIgnoreCase(argv[idx])) {
action = FSConstants.SafeModeAction.SAFEMODE_GET;
waitExitSafe = true;
} else {
printUsage("-safemode");
return;
}
DistributedFileSystem dfs = (DistributedFileSystem) fs;
boolean inSafeMode = dfs.setSafeMode(action);
//
// If we are waiting for safemode to exit, then poll and
// sleep till we are out of safemode.
//
if (waitExitSafe) {
while (inSafeMode) {
try {
Thread.sleep(5000);
} catch (java.lang.InterruptedException e) {
throw new IOException("Wait Interrupted");
}
inSafeMode = dfs.setSafeMode(action);
}
}
System.out.println("Safe mode is " + (inSafeMode ? "ON" : "OFF"));
}
/**
* Command related to decommission of a datanode.
* Usage: java DFSAdmin -decommission [enter | leave | get]
* @param argv List of command line parameters. Each of these items
could be a hostname or a hostname:portname.
* @param idx The index of the command that is being processed.
* @exception IOException if the filesystem does not exist.
* @return 0 on success, non zero on error.
*/
public int decommission(String[] argv, int idx) throws IOException {
int exitCode = -1;
if (!(fs instanceof DistributedFileSystem)) {
System.out.println("FileSystem is " + fs.getName());
return exitCode;
}
if (idx >= argv.length - 1) {
printUsage("-decommission");
return exitCode;
}
//
// Copy all the datanode names to nodes[]
//
String[] nodes = new String[argv.length - idx - 1];
for (int i = idx + 1, j = 0; i < argv.length; i++, j++) {
nodes[j] = argv[i];
}
FSConstants.DecommissionAction action;
if ("set".equalsIgnoreCase(argv[idx])) {
action = FSConstants.DecommissionAction.DECOMMISSION_SET;
} else if ("clear".equalsIgnoreCase(argv[idx])) {
action = FSConstants.DecommissionAction.DECOMMISSION_CLEAR;
} else if ("get".equalsIgnoreCase(argv[idx])) {
action = FSConstants.DecommissionAction.DECOMMISSION_GET;
} else {
printUsage("-decommission");
return exitCode;
}
DistributedFileSystem dfs = (DistributedFileSystem) fs;
boolean mode = dfs.decommission(action, nodes);
if (action == FSConstants.DecommissionAction.DECOMMISSION_GET) {
if (mode) {
System.out.println("Node(s) has finished decommission");
}
else {
System.out.println("Node(s) have not yet been decommissioned");
}
return 0;
}
if (mode) {
return 0; // success
}
return exitCode;
}
/**
* Displays format of commands.
* @param cmd The command that is being executed.
*/
public void printUsage(String cmd) {
if ("-report".equals(cmd)) {
System.err.println("Usage: java DFSAdmin"
+ " [report]");
} else if ("-safemode".equals(cmd)) {
System.err.println("Usage: java DFSAdmin"
+ " [-safemode enter | leave | get | wait]");
} else if ("-decommission".equals(cmd)) {
System.err.println("Usage: java DFSAdmin"
+ " [-decommission set | clear | get "
+ "[datanode1[, datanode2..]]");
} else {
System.err.println("Usage: java DFSAdmin");
System.err.println(" [-report]");
System.err.println(" [-safemode enter | leave | get | wait]");
System.err.println(" [-decommission set | clear | get]");
}
}
/**
* @param argv The parameters passed to this program.
* @exception Exception if the filesystem does not exist.
* @return 0 on success, non zero on error.
*/
public int run(String[] argv) throws Exception {
if (argv.length < 1) {
printUsage("");
return -1;
}
int exitCode = -1;
int i = 0;
String cmd = argv[i++];
//
// verify that we have enough command line parameters
//
if ("-safemode".equals(cmd)) {
if (argv.length != 2) {
printUsage(cmd);
return exitCode;
}
} else if ("-report".equals(cmd)) {
if (argv.length != 1) {
printUsage(cmd);
return exitCode;
}
} else if ("-decommission".equals(cmd)) {
if (argv.length < 2) {
printUsage(cmd);
return exitCode;
}
}
// initialize DFSAdmin
try {
init();
} catch (RPC.VersionMismatch v) {
System.err.println("Version Mismatch between client and server"
+ "... command aborted.");
return exitCode;
} catch (IOException e) {
System.err.println("Bad connection to DFS... command aborted.");
return exitCode;
}
exitCode = 0;
try {
if ("-report".equals(cmd)) {
report();
} else if ("-safemode".equals(cmd)) {
setSafeMode(argv, i);
} else if ("-decommission".equals(cmd)) {
exitCode = decommission(argv, i);
} else {
exitCode = -1;
System.err.println(cmd.substring(1) + ": Unknown command");
printUsage("");
}
} catch (RemoteException e) {
//
// This is a error returned by hadoop server. Print
// out the first line of the error mesage, ignore the stack trace.
exitCode = -1;
try {
String[] content;
content = e.getLocalizedMessage().split("\n");
System.err.println(cmd.substring(1) + ": "
+ content[0]);
} catch (Exception ex) {
System.err.println(cmd.substring(1) + ": "
+ ex.getLocalizedMessage());
}
} catch (IOException e) {
//
// IO exception encountered locally.
//
exitCode = -1;
System.err.println(cmd.substring(1) + ": "
+ e.getLocalizedMessage());
} finally {
fs.close();
}
return exitCode;
}
/**
* main() has some simple utility methods.
* @param argv Command line parameters.
* @exception Exception if the filesystem does not exist.
*/
public static void main(String[] argv) throws Exception {
int res = new DFSAdmin().doMain(new Configuration(), argv);
System.exit(res);
}
}