工做中发如今oozie中使用sqoop与在shell中直接调度sqoop性能上有很大的差别。为了更深刻的探索其中的原因,开始了oozie的源码分析之路。今天第一天阅读源码,因为没有编译成功,不能运行测试用例,直接使用sublime肉眼阅读,仍是挺费劲的。shell
虽然流程还不是顺畅,可是大致上的内容还算是了解了。apache
我这里使用的是oozie4.2的版本,以前稍微看过4.3版本的,源码上仍是有必定的差别的。架构
看上面的图,大体理解oozie的过程是:ide
最重要的就是三个:oop
在启动脚本中oozie.cmd,有这样一句:源码分析
%JAVA_BIN% %JAVA_PROPERTIES% -cp %OOZIECPPATH% org.apache.oozie.cli.OozieCLI %OOZIE_PROPERTIES%
可见,入口在org.apache.oozie.cli.OozieCLI
这个类中,那就从它开始吧。性能
首先是OozieCLI的入口main方法:测试
public static void main(String[] args) { //oozie方法的入口 if (!System.getProperties().containsKey(AuthOozieClient.USE_AUTH_TOKEN_CACHE_SYS_PROP)) { System.setProperty(AuthOozieClient.USE_AUTH_TOKEN_CACHE_SYS_PROP, "true"); } System.exit(new OozieCLI().run(args)); }
前面是一些认证的东西,能够忽略,直接进入run方法:this
public synchronized int run(String[] args) { //保证clent仅启动一次 if (used) { throw new IllegalStateException("CLI instance already used"); } used = true; //建立参数解析器 final CLIParser parser = getCLIParser(); try { final CLIParser.Command command = parser.parse(args); String doAsUser = command.getCommandLine().getOptionValue(DO_AS_OPTION); if (doAsUser != null) { OozieClient.doAs(doAsUser, new Callable<Void>() { @Override public Void call() throws Exception { processCommand(parser, command); return null; } }); } else { processCommand(parser, command); } return 0; } ... }
主要的内容是在这个processCommand里面,processCommand会根据命令调用相应的命令方法:.net
public void processCommand(CLIParser parser, CLIParser.Command command) throws Exception { if (command.getName().equals(HELP_CMD)) { parser.showHelp(command.getCommandLine()); } else if (command.getName().equals(JOB_CMD)) { jobCommand(command.getCommandLine()); } else if (command.getName().equals(JOBS_CMD)) { jobsCommand(command.getCommandLine()); } else if (command.getName().equals(ADMIN_CMD)) { adminCommand(command.getCommandLine()); } else if (command.getName().equals(VERSION_CMD)) { versionCommand(); } else if (command.getName().equals(VALIDATE_CMD)) { validateCommand(command.getCommandLine()); } else if (command.getName().equals(SLA_CMD)) { slaCommand(command.getCommandLine()); } else if (command.getName().equals(PIG_CMD)) { scriptLanguageCommand(command.getCommandLine(), PIG_CMD); } else if (command.getName().equals(HIVE_CMD)) { scriptLanguageCommand(command.getCommandLine(), HIVE_CMD); } else if (command.getName().equals(SQOOP_CMD)) { sqoopCommand(command.getCommandLine());//我关注的sqoop在这里 } else if (command.getName().equals(INFO_CMD)) { infoCommand(command.getCommandLine()); } else if (command.getName().equals(MR_CMD)){ mrCommand(command.getCommandLine()); } }
在sqoopCommand方法里面,sqoop任务被提交:
private void sqoopCommand(CommandLine commandLine) throws IOException, OozieCLIException { List<String> args = commandLine.getArgList(); if (args.size() > 0) { // checking if args starts with -X (because CLIParser cannot check this) if (!args.get(0).equals("-X")) { throw new OozieCLIException("Unrecognized option: " + args.get(0) + " Expecting -X"); } args.remove(0); } if (!commandLine.hasOption(SQOOP_COMMAND_OPTION)) { throw new OozieCLIException("Need to specify -command"); } if (!commandLine.hasOption(CONFIG_OPTION)) { throw new OozieCLIException("Need to specify -config <configfile>"); } try { XOozieClient wc = createXOozieClient(commandLine); Properties conf = getConfiguration(wc, commandLine); String[] command = commandLine.getOptionValues(SQOOP_COMMAND_OPTION); System.out.println(JOB_ID_PREFIX + wc.submitSqoop(conf, command, args.toArray(new String[args.size()]))); } catch (OozieClientException ex) { throw new OozieCLIException(ex.toString(), ex); } }
最重要的内容就在这几行:
XOozieClient wc = createXOozieClient(commandLine); Properties conf = getConfiguration(wc, commandLine); String[] command = commandLine.getOptionValues(SQOOP_COMMAND_OPTION); System.out.println(JOB_ID_PREFIX + wc.submitSqoop(conf, command, args.toArray(new String[args.size()])));
其中wc.submitSqoop提交了sqoop的任务。