zoukankan      html  css  js  c++  java
  • Oozie分布式任务的工作流——Sqoop篇

    Sqoop的使用应该是Oozie里面最常用的了,因为很多BI数据分析都是基于业务数据库来做的,因此需要把mysql或者oracle的数据导入到hdfs中再利用mapreduce或者spark进行ETL,生成报表信息。

    因此本篇的Sqoop Action其实就是运行一个sqoop的任务而已。

    同样action会等到sqoop执行成功后,才会执行下一个action。为了运行sqoop action,需要提供job-tracker,name-node,command或者arg元素。

    sqoop action也可以在开启任务前去创建或者删除hdfs中的目录。

    sqoop action的配置可以通过job-xml指定文件进行配置,也可以直接在configuration元素中配置。

    语法规则

    <workflow-app name="[WF-DEF-NAME]" xmlns="uri:oozie:workflow:0.1">
        ...
        <action name="[NODE-NAME]">
            <sqoop xmlns="uri:oozie:sqoop-action:0.2">
                <job-tracker>[JOB-TRACKER]</job-tracker>
                <name-node>[NAME-NODE]</name-node>
                <prepare>
                   <delete path="[PATH]"/>
                   ...
                   <mkdir path="[PATH]"/>
                   ...
                </prepare>
                <configuration>
                    <property>
                        <name>[PROPERTY-NAME]</name>
                        <value>[PROPERTY-VALUE]</value>
                    </property>
                    ...
                </configuration>
                <command>[SQOOP-COMMAND]</command>
                <arg>[SQOOP-ARGUMENT]</arg>
                ...
                <file>[FILE-PATH]</file>
                ...
                <archive>[FILE-PATH]</archive>
                ...
            </sqoop>
            <ok to="[NODE-NAME]"/>
            <error to="[NODE-NAME]"/>
        </action>
        ...
    </workflow-app>
    
    • prepare元素,用于创建或者删除指定的hdfs目录。
    • job-xml可以指定sqoop action的参数配置
    • confuguration用于配置sqoop任务

    sqoop command

    sqoop命令可以通过command和arg标签组成。

    当使用command元素时,oozie将会按照空格切分命令,作为参数。因此当你使用query的时候,就不能用command了!

    当使用arg的时候,每个arg都是一个参数。

    所有的参数部分,都可以使用EL表达式。

    例子

    基于command的例子

    <workflow-app name="sample-wf" xmlns="uri:oozie:workflow:0.1">
        ...
        <action name="myfirsthivejob">
            <sqoop xmlns="uri:oozie:sqoop-action:0.2">
                <job-tracker>foo:8021</job-tracker>
                <name-node>bar:8020</name-node>
                <prepare>
                    <delete path="${jobOutput}"/>
                </prepare>
                <configuration>
                    <property>
                        <name>mapred.compress.map.output</name>
                        <value>true</value>
                    </property>
                </configuration>
                <command>import  --connect jdbc:hsqldb:file:db.hsqldb --table TT --target-dir hdfs://localhost:8020/user/tucu/foo -m 1</command>
            </sqoop>
            <ok to="myotherjob"/>
            <error to="errorcleanup"/>
        </action>
        ...
    </workflow-app>
    

    基于arg元素的例子

    <workflow-app name="sample-wf" xmlns="uri:oozie:workflow:0.1">
        ...
        <action name="myfirsthivejob">
            <sqoop xmlns="uri:oozie:sqoop-action:0.2">
                <job-tracker>foo:8021</job-tracker>
                <name-node>bar:8020</name-node>
                <prepare>
                    <delete path="${jobOutput}"/>
                </prepare>
                <configuration>
                    <property>
                        <name>mapred.compress.map.output</name>
                        <value>true</value>
                    </property>
                </configuration>
                <arg>import</arg>
                <arg>--connect</arg>
                <arg>jdbc:hsqldb:file:db.hsqldb</arg>
                <arg>--table</arg>
                <arg>TT</arg>
                <arg>--target-dir</arg>
                <arg>hdfs://localhost:8020/user/tucu/foo</arg>
                <arg>-m</arg>
                <arg>1</arg>
            </sqoop>
            <ok to="myotherjob"/>
            <error to="errorcleanup"/>
        </action>
        ...
    </workflow-app>
    

    遇到的问题

    经常会遇到这种问题:直接使用sqoop可以执行,但是在oozie中就无法执行了。这个时候可以按照下面的思路进行排查:

    • 1 oozie中的lib是否与sqoop相同。对比sqoop/lib以及oozie/lib/xxx/sqoop就可以了
    • 2 oozie中如果是以arg这种方式启动。那么问题很有可能出在query的别名以及split-by参数上.... 因为在sqoop中可以自动推断,但是在oozie中就无法知道字段所属的表了。

    举个例子

    sqoop --import .... --query "select a.*,b.* from t1 a left join t2 b on a.id=b.id..." --split-by id ...
    

    这个时候oozie里面,无法知道id到底是哪个表的。需要指定它的别名才可以

    ...
    <arg>--split-by</arg>
    <arg>a.id</arg>
    ...
    
  • 相关阅读:
    Spark安装
    JavaScript encodeURIComponent()
    Kafka分布式:ZooKeeper扩展
    Kafka特性
    Kafka消息topic分区
    Kafka消息文件存储
    哈希表
    sizeof
    pytest_demo_实战2_fixture应用
    pytest_demo_实战1
  • 原文地址:https://www.cnblogs.com/xing901022/p/6091306.html
Copyright © 2011-2022 走看看