大数据之Oozie——源码分析(一)程序入口

工作中发现在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)架构及二次开发流程

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏Java3y

JDBC【数据库连接池、DbUtils框架、分页】

1.数据库连接池 什么是数据库连接池 简单来说:数据库连接池就是提供连接的。。。 为什么我们要使用数据库连接池 数据库的连接的建立和关闭是非常消耗资源的 频繁地...

3724
来自专栏逆向技术

内核开发知识第一讲.内核中的数据类型.重要数据结构.常用内核API函数.

  在内核中.程序的编写不能简单的用基本数据类型了. 因为操作系统不同.很有可能造成数据类型的长度不一.而产生重大问题.所以在内核中.

1532
来自专栏技术小讲堂

WCF中数据契约之已知类型的几种公开方式代码中定义配置中定义宿主端使用解析器

WCF中传输的数据不想传统的面向对象编程,它只传递了一些对象的属性,但是自身并不知道自己属于什么对象,所以,他没有子类和父类的概念,因而也就没有Is-a的关系,...

2803
来自专栏Java编程技术

Velocity引擎原理探究

常见的Java模板引擎有JSP、Freemark,Velocity。在MVC三层框架中,模板引擎属于view层,实质是把model层内容展现到前台页面的一个引擎...

1442
来自专栏知了

ijst:基于反射的 C++ JSON 反序列化库

ijst (iJsonStruct) 一个是 C++ Json 序列化/反序列化库:

2775
来自专栏与神兽党一起成长

jFinal路由解析源码分析

jFinal的路由解析是在JFinalFilter中做的,这个Filter也需要在web.xml中配置。JFinalFilter实现了javax.servlet...

1492
来自专栏Jed的技术阶梯

zookeeper案例之4个逻辑思维训练小题目

1222
来自专栏你不就像风一样

Jsoup模拟登录带验证码的教务系统(原理详解)

在模拟登陆该教务系统时,笔者观察到该教务系统还有一个不需要验证码即可登陆的网址:http://jwxt.qlu.edu.cn/jsxsd/xsxk/xklc_l...

1372
来自专栏haifeiWu与他朋友们的专栏

造个轮子之基于 Netty 实现自己的 RPC 框架

服务端开发都会或多或少的涉及到 RPC 的使用,当然如果止步于会用,对自己的成长很是不利,所以楼主今天本着知其然,且知其所以然的精神来探讨一下 RPC 这个东西...

1513
来自专栏嵌入式程序猿

ARM cortexM4异常处理(2)

上次课程我们简单讲解了异常的一些基础知识,希望对大家有所帮助,今天我们来看看异常在向量表中的位置,异常的入口和返回。 中断向量表 有人会问,不是讲异常吗,怎么...

3647

扫码关注云+社区

领取腾讯云代金券