工做中發如今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的任務。