工作中发现在oozie中使用sqoop与在shell中直接调度sqoop性能上有很大的差异。为了更深入的探索其中的缘由,开始了oozie的源码分析之路。今天第一天阅读源码,由于没有编译成功,不能运行测试用例,直接使用sublime肉眼阅读,还是挺费劲的。

虽然流程还不是顺畅,但是大体上的内容还算是了解了。

我这里使用的是oozie4.2的版本,之前稍微看过4.3版本的,源码上还是有一定的差异的。

看上面的图,大致理解oozie的过程是:

  • oozie cli提交任务
  • oozie server创建一个对应任务的client
  • client去提交相应的任务

oozie工程结构

最重要的就是三个:

  • 1 client 这是任务提交的入口
  • 2 core 这是oozie的核心(在3中好像拆分成了core和server)
  • 3 distro 这里保存了启动脚本

寻找源码入口

  • 一种方式是直接以文件夹搜索main方法。
  • 另一种是看它的启动脚本。

在启动脚本中oozie.cmd,有这样一句:

%JAVA_BIN% %JAVA_PROPERTIES% -cp %OOZIECPPATH% org.apache.oozie.cli.OozieCLI %OOZIE_PROPERTIES%

可见,入口在org.apache.oozie.cli.OozieCLI这个类中,那就从它开始吧。

sqoop作业的提交

首先是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方法:

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会根据命令调用相应的命令方法:

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的任务。

后续问题

  • 1 任务提交到了哪里?
  • 2 在提交任务的时候都做了很么?
  • 3 如何在mapreduce开启一个新的sqoop的?
  • 4 为什么在yarn中可以同时看到两个应用,一个oozie,一个是sqoop

参考

1 oozie(4.1.0)架构及二次开发流程

大数据之Oozie——源码分析(一)程序入口的更多相关文章

  1. MYC编译器源码分析之程序入口

    前文.NET框架源码解读之MYC编译器讲了MyC编译器的架构,整个编译器是用C#语言写的,上图列出了MyC编译器编译一个C源文件的过程,编译主路径如下: 首先是入口Main函数用来解析命令行参数,读取 ...

  2. 图解Janusgraph系列-图数据底层序列化源码分析(Data Serialize)

    图解Janusgraph系列-图数据底层序列化源码分析(Data Serialize) 大家好,我是洋仔,JanusGraph图解系列文章,实时更新~ 图数据库文章总目录: 整理所有图相关文章,请移步 ...

  3. Golang package轻量级KV数据缓存——go-cache源码分析

    作者:Moon-Light-Dream 出处:https://www.cnblogs.com/Moon-Light-Dream/ 转载:欢迎转载,但未经作者同意,必须保留此段声明:必须在文章中给出原文 ...

  4. 【大数据】深入源码解析Map Reduce的架构

    这几天学习了MapReduce,我参照资料,自己又画了两张MapReduce的架构图. 这里我根据架构图以及对应的源码,来解释一次分布式MapReduce的计算到底是怎么工作的. ​话不多说,开始! ...

  5. MongoDB源码分析——mongod程序源码入口分析

    Edit 说明:第一次写笔记,之前都是看别人写的,觉得很简单,开始写了之后才发现真的很难,不知道该怎么分析,这篇文章也参考了很多前辈对MongoDB源码的分析,也有一些自己的理解,后续将会继续分析其他 ...

  6. MongoDB源码分析——mongo主程序入口分析

    Edit   源码版本为MongoDB 2.6分支 mongo主程序入口分析 mongo是MongoDB提供的一个执行JavaScript脚本的客户端工具,可以用来和服务端交互,2.6版本的Mongo ...

  7. yii2 源码分析1从入口开始

    我是在 backend 一步步打印的 很多地方我也是很模糊 .后来发现一位大神的文章(http://www.yiichina.com/tutorial/773) 参考文章自己动手开始写的 至于后来的 ...

  8. Django源码分析之程序执行入口分析

    一般我们开启一个django项目,最简单的方法是进入project 目录,这时目录结构是这样的 然后我们执行python manage.py runserver,程序就开始执行了. 那django是如 ...

  9. Django源码分析之执行入口

    魔法门 一般我们启动django,最简单的方法是进入project 目录,这时目录结构是这样的 然后我们执行python manage.py runserver,程序就开始执行了. 那django是如 ...

随机推荐

  1. 分布式锁1 Java常用技术方案

    前言:       由于在平时的工作中,线上服务器是分布式多台部署的,经常会面临解决分布式场景下数据一致性的问题,那么就要利用分布式锁来解决这些问题.所以自己结合实际工作中的一些经验和网上看到的一些资 ...

  2. PHP与API讲解(一)

    了解API: 在使用与创建自己的API之前我们需要先了解什么是API! API代表应用程序编程接口,而接口指的是一个特定的服务.一个应用程序或者其他程序的公共模块. 理解SOA(面向服务的架构):SO ...

  3. Oracle数据库该如何着手优化一个SQL

    这是个终极问题,因为优化本身的复杂性实在是难以总结的,很多时候优化的方法并不是用到了什么高深莫测的技术,而只是一个思想意识层面的差异,而这些都很可能连带导致性能表现上的巨大差异. 所以有时候我们应该先 ...

  4. MyBatis基础入门--知识点总结

    对原生态jdbc程序的问题总结 下面是一个传统的jdbc连接oracle数据库的标准代码: public static void main(String[] args) throws Exceptio ...

  5. 使用RequireJS并实现一个自己的模块加载器 (一)

    RequireJS & SeaJS 在 模块化开发 开发以前,都是直接在页面上引入 script 标签来引用脚本的,当项目变得比较复杂,就会带来很多问题. JS项目中的依赖只有通过引入JS的顺 ...

  6. 从啥也不会到可以胜任最基本的JavaWeb工作,推荐给新人的学习路线(二)

    在上一节中,主要阐述了JavaScript方面的学习路线.先列举一下我朋友的经历,他去过培训机构,说是4个月后月薪过万,虽然他现在还未达到这个指标. 培训机构一般的套路是这样:先教JavaSE,什么都 ...

  7. WPF中Grid实现网格,表格样式通用类

    /// <summary> /// 给Grid添加边框线 /// </summary> /// <param name="grid"></ ...

  8. .NET - 基于事件的异步模型

    注:这是大概四年前写的文章了.而且我离开.net领域也有四年多了.本来不想再发表,但是这实际上是Active Object模式在.net中的一种重要实现方法,因此我把它掏出来发布一下.如果该模型有新的 ...

  9. 程序猿是如何解决SQLServer占CPU100%的

    文章目录 遇到的问题 使用SQLServer Profiler监控数据库 SQL1:查找最新的30条告警事件 SQL2:获取当前的总报警记录数 有哪些SQL语句会导致CPU过高? 查看SQL的查询计划 ...

  10. 【初探Spring】------Spring IOC(二):初始化过程---简介

    首先我们先来看看如下一段代码 ClassPathResource resource = new ClassPathResource("bean.xml"); DefaultList ...