RICH-ATONE

Oozie介绍与相关使用

oozie

Oozie工作流程定义是一个DAG(Directed Acyclical Graphs)图,它由控制流节点(Control Flow Nodes)或动作节点(Action Nodes)组成

官网:http://oozie.apache.org/

一.功能模块:

  1. Workflow 顺序执行流程节点,支持fork(分支多个节点),join(合并多个节点为一个)

  2. Coordinator 定时触发workflow

  3. Bundle Job 绑定多个Coordinator

  4. job.properties 配置相关文件设置

 

 

配置相关文件

 

Bundle设置参考:https://blog.csdn.net/goodstuddayupyyeah/article/details/74521285

工作流生命周期

在Oozie中,工作流的状态可能存在如下几种:

状态
含义说明
PREP 一个工作流Job第一次创建将处于PREP状态,表示工作流Job已经定义,但是没有运行。
RUNNING 当一个已经被创建的工作流Job开始执行的时候,就处于RUNNING状态。它不会达到结束状态,只能因为出错而结束,或者被挂起。
SUSPENDED 一个RUNNING状态的工作流Job会变成SUSPENDED状态,而且它会一直处于该状态,除非这个工作流Job被重新开始执行或者被杀死。
SUCCEEDED 当一个RUNNING状态的工作流Job到达了end节点,它就变成了SUCCEEDED最终完成状态。
KILLED 当一个工作流Job处于被创建后的状态,或者处于RUNNING、SUSPENDED状态时,被杀死,则工作流Job的状态变为KILLED状态。
FAILED 当一个工作流Job不可预期的错误失败而终止,就会变成FAILED状态。

控制流节点

工作流中的控制节点,主要控制工作流的开始、结束、及执行路径。主要包括为:start、end、kill、decision、fork、join节点。

动作节点

Ssh Action

  <action name="[NODE-NAME]">
      <ssh>
          <host>[USER]@[HOST]</host>
          <command>[SHELL]</command>
          <args>[ARGUMENTS]</args>
          ...
          <capture-output />
      </ssh>
      <ok to="[NODE-NAME]" />
      <error to="[NODE-NAME]" />
  </action>

 

Email Action

  <action name="failed-email">
      <email xmlns="uri:oozie:email-action:0.1">
          <to>oozie-transfer@bj.babeltime.cn</to>
          <subject>${jobName} ${yesterday} failed for oozie</subject>
          <body>${jobName} ${yesterday} failed, error message[${wf:errorMessage(wf:lastErrorNode())}]</body>
      </email>
      <ok to="fail"/>
      <error to="fail"/>
  </action>

Shell Action

  <action name="delete_mysql">
    <ssh xmlns="uri:oozie:ssh-action:0.2">
          <host>192.168.10.241</host>
          <command>/bin/bash</command>
          <arg>${sshUri}/preparam.sh</arg>
          <arg>${mysql_host}</arg>
          <arg>${mysql_user}</arg>
          <arg>${mysql_pwd}</arg>
          <arg>${timezone}</arg>
          <arg>${gn}</arg>
          <arg>${ds}</arg>
          <capture-output/>
      </ssh>
      <ok to="XXXX"/>
      <error to="XXXX"/>
  </action>

Hive Action

  <action name="myfirsthivejob">
      <hive xmlns="uri:oozie:hive-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>
          <script>myscript.q</script>
          <param>InputDir=/home/tucu/input-data</param>
          <param>OutputDir=${jobOutput}</param>
      </hive>
      <ok to="myotherjob"/>
      <error to="errorcleanup"/>
  </action>

Sqoop Action

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

Pig Action

<workflow-app>
...
<action name="[NODE-NAME]">
<pig>
...
<script>[PIG-SCRIPT]</script>
<argument>[ARGUMENT-VALUE]</argument>
...
<argument>[ARGUMENT-VALUE]</argument>

...
</pig>
<ok to="[NODE-NAME]"/>
<error to="[NODE-NAME]"/>
</action>
...
</workflow-app>

Fs Action

<workflow-app name="[WF-DEF-NAME]" xmlns="uri:oozie:workflow:0.1">
  ...
  <action name="[NODE-NAME]">
      <fs>
          <delete path='[PATH]' />
          ...
          <mkdir path='[PATH]' />
          ...
          <move source='[SOURCE-PATH]' target='[TARGET-PATH]' />
          ...
          <chmod path='[PATH]' permissions='[PERMISSIONS]' dir-files='false' />
          ...
          <touchz path='[PATH]' />
      </fs>
      <ok to="[NODE-NAME]" />
      <error to="[NODE-NAME]" />
  </action>
  ...
</workflow-app>

Java Action

Java动作,是执行一个具有main入口方法的应用程序,在Oozie工作流定义中,会作为一个MapReduce Job执行,这个Job只有一个Map任务。我们需要指定NameNode、JobTracker的信息,还有配置一个Java应用程序的JVM选项参数(java-opts),以及传给主函数(arg)。 语法格式:

<workflow-app name="[WF-DEF-NAME]" xmlns="uri:oozie:workflow:0.1">
  ...
  <action name="[NODE-NAME]">
      <java>
          <job-tracker>[JOB-TRACKER]</job-tracker>
          <name-node>[NAME-NODE]</name-node>
          <prepare>
              <delete path="[PATH]" />
              ...
              <mkdir path="[PATH]" />
              ...
          </prepare>
          <job-xml>[JOB-XML]</job-xml>
          <configuration>
              <property>
                  <name>[PROPERTY-NAME]</name>
                  <value>[PROPERTY-VALUE]</value>
              </property>
              ...
          </configuration>
          <main-class>[MAIN-CLASS]</main-class>
          <java-opts>[JAVA-STARTUP-OPTS]</java-opts>
          <arg>ARGUMENT</arg>
          ...
          <file>[FILE-PATH]</file>
          ...
          <archive>[FILE-PATH]</archive>
          ...
          <capture-output />
      </java>
      <ok to="[NODE-NAME]" />
      <error to="[NODE-NAME]" />
  </action>
  ...
</workflow-app>

Sub-workflow动作

<workflow-app name="[WF-DEF-NAME]" xmlns="uri:oozie:workflow:0.4">
  ...
  <action name="[NODE-NAME]">
      <shell xmlns="uri:oozie:shell-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>
          <exec>[SHELL-COMMAND]</exec>
          <argument>[ARGUMENT-VALUE]</argument>
          <capture-output />
      </shell>
      <ok to="[NODE-NAME]" />
      <error to="[NODE-NAME]" />
  </action>
  ...
</workflow-app>

Oozie常用调度文件编写

workflow

<workflow-app xmlns="uri:oozie:workflow:0.5" name="${jobName}">
    
    <global>
      <job-tracker>${jobTracker}</job-tracker>
      <name-node>${nameNode}</name-node>
      <configuration>
        <property>
          <name>mapred.job.queue.name</name>
          <value>${queueName}</value>
        </property>
        <property>
          <name>oozie.launcher.mapred.job.queue.name</name>
          <value>${launcher_queName}</value>
        </property>
      </configuration>
    </global>

 <start to="mysql_to_hive"/>

<action name="mysql_to_hive">
    <ssh xmlns="uri:oozie:ssh-action:0.2">
      <host>xxx.xxx.xx.xxx</host>
      <command>/bin/bash</command>
      <arg>/home/pirate/project/mysql_to_hive/xxx_dev_settings.sh</arg>
      <capture-output/>
    </ssh>
    <ok to="dev_fork"/>
    <error to="fail"/>
</action>

<fork name = 'dev_fork'>
<path start="xxx_dev_bag_stat"/>
<path start="xxx_dev_collect_stat"/>
<path start="xxx_dev_daily_bag_stat"/>
<path start="xxx_dev_exchange_stat"/>
<path start="xxx_dev_vip_statistic"/>
</fork>

        <action name="xxx_dev_bag_stat">
                <sub-workflow>
                        <app-path>${baseUri}/xxx_dev_bag_stat</app-path>
                        <propagate-configuration/>
                </sub-workflow>
                <ok to="dev_join"/>
                <error to="fail"/>
        </action>

  <action name="xxx_dev_collect_stat">
    <sub-workflow>
      <app-path>${baseUri}/xxx_dev_collect_stat</app-path>
      <propagate-configuration/>
    </sub-workflow>
    <ok to="dev_join"/>
    <error to="fail"/>
  </action>


    <action name="xxx_dev_daily_bag_stat">
    <sub-workflow>
      <app-path>${baseUri}/xxx_dev_daily_bag_stat</app-path>
      <propagate-configuration/>
    </sub-workflow>
    <ok to="dev_join"/>
    <error to="fail"/>
  </action>




    <action name="xxx_dev_exchange_stat">
    <sub-workflow>
      <app-path>${baseUri}/xxx_dev_exchange_stat</app-path>
      <propagate-configuration/>
    </sub-workflow>
    <ok to="dev_join"/>
    <error to="fail"/>
  </action>


    <action name="xxx_dev_vip_statistic">
    <sub-workflow>
      <app-path>${baseUri}/xxx_dev_vip_statistic</app-path>
      <propagate-configuration/>
    </sub-workflow>
    <ok to="dev_join"/>
    <error to="fail"/>
  </action>

  <join name="dev_join" to ="update_settings"/>

        <action name="update_settings">
          <ssh xmlns="uri:oozie:ssh-action:0.2">
          <host>xxx.xxx.xx.xxx</host>
          <command>/bin/bash</command>
          <arg>${sshUri}/preparam.sh</arg>
          <arg>${mysql_host}</arg>
          <arg>${mysql_user}</arg>
          <arg>${mysql_pwd}</arg>
          <arg>${timezone}</arg>
          <arg>${gn}</arg>
          <arg>${ds}</arg>
          <capture-output/>
          </ssh> 
           <ok to="end"/>
           <error to="fail"/>
        </action>


    <kill name="fail">
        <message>job failed, error message[${wf:errorMessage(wf:lastErrorNode())}]</message>
    </kill>

    <end name="end"/>

</workflow-app>

coordinator.xml

            <coordinator-app name="${jobName}" frequency="0 10 * * *" start="${start}" end="${end}" timezone="GMT+0800"
            xmlns="uri:oozie:coordinator:0.4">
            <action>
            <workflow>
            <app-path>${workflowAppUri}</app-path>
            <configuration>
            <property>
            <name>ds</name>
            <value>${coord:formatTime(coord:dateOffset(coord:nominalTime(), -1, 'DAY'), 'yyyy-MM-dd')}</value>
            </property>

       <property>
       <name>year</name>
       <value>${coord:formatTime(coord:dateOffset(coord:nominalTime(), -1, 'DAY'), 'yyyy')}</value>
       </property>

            <property>
            <name>mysql_host</name>
            <value>${mysql_host}</value>
            </property>
            <property>
            <name>mysql_user</name>
            <value>${mysql_user}</value>
            </property>
            <property>
            <name>mysql_pwd</name>
            <value>${mysql_pwd}</value>
            </property>
            </configuration>
            </workflow>
            </action>
            </coordinator-app>

job.properties 

nameNode=hdfs://mycluster
jobTracker=hadoop02:8042
queueName=default
launcher_queName=oozie
jobName=xxxx
mysql_host=xxx.xxx.xx.xxx
mysql_user=xxxx
mysql_pwd=xxxx

gn=xxx
timezone=GMT+8

oozie.use.system.libpath=true
sshUri=/home/xxxx/xxx/xxxx
workflowAppUri=${nameNode}/user/xxxx/project/xxxx
baseUri=${nameNode}/user/xxxx/project/xxxx
#oozie.wf.application.path=${workflowAppUri}
oozie.coord.application.path=${workflowAppUri}
start=2020-01-13T03:30+0800
end=9999-12-31T23:00+0800

 

EL表达式:

常用表达式:

昨天: ${coord:formatTime(coord:dateOffset(coord:nominalTime(),-1,'DAY'),'yyyy-MM-dd')}

上月: ${coord:formatTime(coord:dateOffset(coord:nominalTime(),-1,'MONTH'),'yyyy-MM')}

注意: 一定要大写DAY,MONTH

常量表示形式
含义说明
常量表示形式
含义说明
${coord:minutes(int n)} 返回日期时间:从一开始,周期执行n分钟
${coord:hours(int n)} 返回日期时间:从一开始,周期执行n * 60分钟
${coord:days(int n)} 返回日期时间:从一开始,周期执行n * 24 * 60分钟
${coord:months(int n)} 返回日期时间:从一开始,周期执行n * M * 24 * 60分钟(M表示一个月的天数)
${coord:endOfDays(int n)} 返回日期时间:从当天的最晚时间(即下一天)开始,周期执行n * 24 * 60分钟
${coord:endOfMonths(1)} 返回日期时间:从当月的最晚时间开始(即下个月初),周期执行n * 24 * 60分钟
${coord:current(int n)} 返回日期时间:从一个Coordinator动作(Action)创建时开始计算,第n个dataset实例执行时间
${coord:dataIn(String name)} 在输入事件(input-events)中,解析dataset实例包含的所有的URI
${coord:dataOut(String name)} 在输出事件(output-events)中,解析dataset实例包含的所有的URI
${coord:offset(int n, String timeUnit)} 表示时间偏移,如果一个Coordinator动作创建时间为T,n为正数表示向时刻T之后偏移,n为负数向向时刻T之前偏移,timeUnit表示时间单位(选项有MINUTE、HOUR、DAY、MONTH、YEAR)
${coord:hoursInDay(int n)} 指定的第n天的小时数,n>0表示向后数第n天的小时数,n=0表示当天小时数,n<0表示向前数第n天的小时数
${coord:daysInMonth(int n)} 指定的第n个月的天数,n>0表示向后数第n个月的天数,n=0表示当月的天数,n<0表示向前数第n个月的天数
${coord:tzOffset()} ataset对应的时区与Coordinator Job的时区所差的分钟数
${coord:latest(int n)} 最近以来,当前可以用的第n个dataset实例
${coord:future(int n, int limit)} 当前时间之后的dataset实例,n>=0,当n=0时表示立即可用的dataset实例,limit表示dataset实例的个数
${coord:nominalTime()} nominal时间等于Coordinator Job启动时间,加上多个Coordinator Job的频率所得到的日期时间。例如:start=”2009-01-01T24:00Z”,end=”2009-12-31T24:00Z”,frequency=”{coord:days(1)},则nominal时间为:2009-01-02T00:00Z、2009-01-03T00:00Z、2009-01-04T00:00Z、…、2010-01-01T00:00Z
${coord:actualTime()} Coordinator动作的实际创建时间。例如:start=”2011-05-01T24:00Z”,end=”2011-12-31T24:00Z”,frequency=”${coord:days(1)}”,则实际时间为:2011-05-01,2011-05-02,2011-05-03,…,2011-12-31
${coord:user()} 启动当前Coordinator Job的用户名称
${coord:dateOffset(String baseDate, int instance, String timeUnit)} 计算新的日期时间的公式:newDate = baseDate + instance * timeUnit,如:baseDate=’2009-01-01T00:00Z’,instance=’2′,timeUnit=’MONTH’,则计算得到的新的日期时间为’2009-03-01T00:00Z’。
${coord:formatTime(String timeStamp, String format)} 格式化时间字符串,format指定模式

 

参考:http://shiyanjun.cn/archives/664.html

posted on 2020-11-08 22:06  RICH-ATONE  阅读(385)  评论(0编辑  收藏  举报

导航