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>
...


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM