Oozie多任務串聯和定時任務執行?看這篇就懂了!

寫在前面: 博主是一名軟件工程系大數據應用開發專業大二的學生,暱稱來源於《愛麗絲夢遊仙境》中的Alice和自己的暱稱。作爲一名互聯網小白,寫博客一方面是爲了記錄自己的學習歷程,一方面是希望能夠幫助到很多和自己一樣處於起步階段的萌新。由於水平有限,博客中難免會有一些錯誤,有紕漏之處懇請各位大佬不吝賜教!個人小站:http://alices.ibilibili.xyz/ , 博客主頁:https://alice.blog.csdn.net/
儘管當前水平可能不及各位大佬,但我還是希望自己能夠做得更好,因爲一天的生活就是一生的縮影。我希望在最美的年華,做最好的自己

        在上一篇博客中,博主爲大家帶來了Oozie的簡介,以及常用的基礎操作,包括使用Oozie調度shell腳本,hive,mapreduce…(👉什麼是Oozie?如何使用Oozie?蒟蒻博主帶你快速上手Oozie!)。
        本篇博客,爲大家介紹的則是Oozie的任務串聯和任務調度
在這裏插入圖片描述


Oozie的任務串聯

        在實際工作當中,肯定會存在多個任務需要執行,並且存在上一個任務的輸出結果作爲下一個任務的輸入數據這樣的情況,所以我們需要在workflow.xml配置文件當中配置多個action,實現多個任務之間的相互依賴關係。

        例如現在有一個需求:首先執行一個shell腳本,執行完了之後再執行一個MR的程序,最後再執行一個hive的程序。

        我們應該怎麼實現呢?

第一步:準備工作目錄

cd /export/servers/oozie-4.1.0-cdh5.14.0/oozie_works
mkdir -p sereval-actions

第二步:準備調度文件
        將我們之前的hive,shell,以及MR的執行,進行串聯成到一個workflow當中去,準備資源文件。

cd /export/servers/oozie-4.1.0-cdh5.14.0/oozie_works
cp hive2/script.q    sereval-actions/
cp shell/hello.sh    sereval-actions/
cp -ra map-reduce/lib    sereval-actions/

第三步:開發調度的配置文件

cd /export/servers/oozie-4.1.0-cdh5.14.0/oozie_works/sereval-actions

創建配置文件workflow.xml並編輯
vim workflow.xml

<workflow-app xmlns="uri:oozie:workflow:0.4" name="shell-wf">
<start to="shell-node"/>
<action name="shell-node">
    <shell xmlns="uri:oozie:shell-action:0.2">
        <job-tracker>${jobTracker}</job-tracker>
        <name-node>${nameNode}</name-node>
        <configuration>
            <property>
                <name>mapred.job.queue.name</name>
                <value>${queueName}</value>
            </property>
        </configuration>
        <exec>${EXEC}</exec>
        <!-- <argument>my_output=Hello Oozie</argument> -->
        <file>/user/root/oozie_works/sereval-actions/${EXEC}#${EXEC}</file>

        <capture-output/>
    </shell>
    <ok to="mr-node"/>
    <error to="mr-node"/>
</action>




<action name="mr-node">
        <map-reduce>
            <job-tracker>${jobTracker}</job-tracker>
            <name-node>${nameNode}</name-node>
            <prepare>
                <delete path="${nameNode}/${outputDir}"/>
            </prepare>
            <configuration>
                <property>
                    <name>mapred.job.queue.name</name>
                    <value>${queueName}</value>
                </property>
				<!--  
                <property>
                    <name>mapred.mapper.class</name>
                    <value>org.apache.oozie.example.SampleMapper</value>
                </property>
                <property>
                    <name>mapred.reducer.class</name>
                    <value>org.apache.oozie.example.SampleReducer</value>
                </property>
                <property>
                    <name>mapred.map.tasks</name>
                    <value>1</value>
                </property>
                <property>
                    <name>mapred.input.dir</name>
                    <value>/user/${wf:user()}/${examplesRoot}/input-data/text</value>
                </property>
                <property>
                    <name>mapred.output.dir</name>
                    <value>/user/${wf:user()}/${examplesRoot}/output-data/${outputDir}</value>
                </property>
				-->
				
				   <!-- 開啓使用新的API來進行配置 -->
                <property>
                    <name>mapred.mapper.new-api</name>
                    <value>true</value>
                </property>

                <property>
                    <name>mapred.reducer.new-api</name>
                    <value>true</value>
                </property>

                <!-- 指定MR的輸出key的類型 -->
                <property>
                    <name>mapreduce.job.output.key.class</name>
                    <value>org.apache.hadoop.io.Text</value>
                </property>

                <!-- 指定MR的輸出的value的類型-->
                <property>
                    <name>mapreduce.job.output.value.class</name>
                    <value>org.apache.hadoop.io.IntWritable</value>
                </property>

                <!-- 指定輸入路徑 -->
                <property>
                    <name>mapred.input.dir</name>
                    <value>${nameNode}/${inputdir}</value>
                </property>

                <!-- 指定輸出路徑 -->
                <property>
                    <name>mapred.output.dir</name>
                    <value>${nameNode}/${outputDir}</value>
                </property>

                <!-- 指定執行的map類 -->
                <property>
                    <name>mapreduce.job.map.class</name>
                    <value>org.apache.hadoop.examples.WordCount$TokenizerMapper</value>
                </property>

                <!-- 指定執行的reduce類 -->
                <property>
                    <name>mapreduce.job.reduce.class</name>
                    <value>org.apache.hadoop.examples.WordCount$IntSumReducer</value>
                </property>
				<!--  配置map task的個數 -->
                <property>
                    <name>mapred.map.tasks</name>
                    <value>1</value>
                </property>

            </configuration>
        </map-reduce>
        <ok to="hive2-node"/>
        <error to="fail"/>
    </action>






 <action name="hive2-node">
        <hive2 xmlns="uri:oozie:hive2-action:0.1">
            <job-tracker>${jobTracker}</job-tracker>
            <name-node>${nameNode}</name-node>
            <prepare>
                <delete path="${nameNode}/user/${wf:user()}/${examplesRoot}/output-data/hive2"/>
                <mkdir path="${nameNode}/user/${wf:user()}/${examplesRoot}/output-data"/>
            </prepare>
            <configuration>
                <property>
                    <name>mapred.job.queue.name</name>
                    <value>${queueName}</value>
                </property>
            </configuration>
            <jdbc-url>${jdbcURL}</jdbc-url>
            <script>script.q</script>
            <param>INPUT=/user/${wf:user()}/${examplesRoot}/input-data/table</param>
            <param>OUTPUT=/user/${wf:user()}/${examplesRoot}/output-data/hive2</param>
        </hive2>
        <ok to="end"/>
        <error to="fail"/>
    </action>
<decision name="check-output">
    <switch>
        <case to="end">
            ${wf:actionData('shell-node')['my_output'] eq 'Hello Oozie'}
        </case>
        <default to="fail-output"/>
    </switch>
</decision>
<kill name="fail">
    <message>Shell action failed, error message[${wf:errorMessage(wf:lastErrorNode())}]</message>
</kill>
<kill name="fail-output">
    <message>Incorrect output, expected [Hello Oozie] but was [${wf:actionData('shell-node')['my_output']}]</message>
</kill>
<end name="end"/>
</workflow-app>

開發job.properties配置文件

cd /export/servers/oozie-4.1.0-cdh5.14.0/oozie_works/sereval-actions
vim  job.properties
nameNode=hdfs://bd001:8020
jobTracker=bd001:8032
queueName=default
examplesRoot=oozie_works
EXEC=hello.sh
outputDir=/oozie/output
inputdir=/oozie/input
jdbcURL=jdbc:hive2://node03:10000/default
oozie.use.system.libpath=true
# 配置我們文件上傳到hdfs的保存路徑 實際上就是在hdfs 的/user/root/oozie_works/sereval-actions這個路徑下
oozie.wf.application.path=${nameNode}/user/${user.name}/${examplesRoot}/sereval-actions/workflow.xml

第四步:上傳資源文件夾到hdfs對應路徑

cd /export/servers/oozie-4.1.0-cdh5.14.0/oozie_works/
hdfs dfs -put sereval-actions/ /user/root/oozie_works/

第五步:執行調度任務

cd /export/servers/oozie-4.1.0-cdh5.14.0/
bin/oozie job -oozie http://bd001:11000/oozie -config oozie_works/sereval-actions/job.properties -run

正確執行完調度任務,我們能發現跟上一篇Oozie三次單獨調度後的效果一致。說明我們使用Oozie的任務串聯就成功了!

在這裏插入圖片描述
下面我們來侃侃Oozie的任務調度。

Oozie的任務調度,定時任務執行

        在oozie當中,主要是通過Coordinator 來實現任務的定時調度,與workflow類似的,Coordinator 這個模塊也是主要通過xml來進行配置即可,接下來我們就來看看如何配置Coordinator 來實現任務的定時調度。

        Coordinator 的調度主要可以有兩種實現方式

        第一種:基於時間的定時任務調度

        oozie基於時間的調度主要需要指定三個參數,第一個起始時間,第二個結束時間,第三個調度頻率。

        第二種:基於數據的任務調度

        這種是基於數據的調度,只要在有了數據纔會觸發調度任務。

Oozie當中定時任務的設置

第一步:拷貝定時任務的調度模板

cd /export/servers/oozie-4.1.0-cdh5.14.0
cp -r examples/apps/cron oozie_works/cron-job

第二步:拷貝hello.sh腳本

cd /export/servers/oozie-4.1.0-cdh5.14.0/oozie_works
cp shell/hello.sh  cron-job/

第三步:修改配置文件

修改job.properties

cd /export/servers/oozie-4.1.0-cdh5.14.0/oozie_works/cron-job
vim job.properties
nameNode=hdfs://bd001:8020
jobTracker=bd001:8032
queueName=default
examplesRoot=oozie_works

oozie.coord.application.path=${nameNode}/user/${user.name}/${examplesRoot}/cron-job/coordin
ator.xml
start=2020-06-01T00:00+0800
end=2020-06-02T00:00+0800
EXEC=hello.sh
workflowAppUri=${nameNode}/user/${user.name}/${examplesRoot}/cron-job/workflow.xml

修改coordinator.xml
vim coordinator.xml

<!--
	oozie的frequency 可以支持很多表達式,其中可以通過定時每分,或者每小時,或者每天,或者每月進行執行,也支持可以通過與linux的crontab表達式類似的寫法來進行定時任務的執行
	例如frequency 也可以寫成以下方式
	frequency="10 9 * * *"  每天上午的09:10:00開始執行任務
	frequency="0 1 * * *"  每天凌晨的01:00開始執行任務
 -->
<coordinator-app name="cron-job" frequency="${coord:minutes(1)}" start="${start}" end="${end}" timezone="GMT+0800"
                 xmlns="uri:oozie:coordinator:0.4">
        <action>
        <workflow>
            <app-path>${workflowAppUri}</app-path>
            <configuration>
                <property>
                    <name>jobTracker</name>
                    <value>${jobTracker}</value>
                </property>
                <property>
                    <name>nameNode</name>
                    <value>${nameNode}</value>
                </property>
                <property>
                    <name>queueName</name>
                    <value>${queueName}</value>
                </property>
            </configuration>
        </workflow>
    </action>
</coordinator-app>

修改workflow.xml
vim workflow.xml

<workflow-app xmlns="uri:oozie:workflow:0.5" name="one-op-wf">
    <start to="action1"/>
    <action name="action1">
    <shell xmlns="uri:oozie:shell-action:0.2">
        <job-tracker>${jobTracker}</job-tracker>
        <name-node>${nameNode}</name-node>
        <configuration>
            <property>
                <name>mapred.job.queue.name</name>
                <value>${queueName}</value>
            </property>
        </configuration>
        <exec>${EXEC}</exec>
        <!-- <argument>my_output=Hello Oozie</argument> -->
        <file>/user/root/oozie_works/cron-job/${EXEC}#${EXEC}</file>
         
        <capture-output/>
    </shell>
    <ok to="end"/>
    <error to="end"/>
</action>
    <end name="end"/>
</workflow-app>

第四步:上傳到hdfs對應路徑

cd /export/servers/oozie-4.1.0-cdh5.14.0/oozie_works
hdfs dfs -put cron-job/ /user/root/oozie_works/

第五步:運行定時任務

cd /export/servers/oozie-4.1.0-cdh5.14.0
bin/oozie job -oozie http://bd001:11000/oozie -config oozie_works/cron-job/job.properties -run

運行定時任務的命令執行完畢,我們先去Oozie的web頁面上查看任務進程狀態
在這裏插入圖片描述
如果是success成功的狀態,我們就可以根據我們設置的shell命令,在linux上查看效果。

在這裏插入圖片描述
根據我們shell腳本設置的內容,再加上在job.properties中設置的2020年6月1日到6月2日期間,每隔一分鐘就執行一次。

當我們一會再去看腳本指定輸出路徑時
vim /export/servers/tmp/hello_oozie.txt

在這裏插入圖片描述
可以發現已經有了很多行的hello world

看到這裏,如果你也成功跑出了效果,不妨給自己一個贊!
在這裏插入圖片描述

Oozie常用命令

查看所有普通任務

oozie jobs -oozie http://bd001:11000/oozie

查看定時任務

oozie jobs -oozie http://bd001:11000/oozie   -jobtype coordinator

殺死某個任務

oozie可以通過jobid來殺死某個定時任務

oozie job -oozie http://bd001:11000/oozie -kill 0000033-200526143050941-oozie-root-W

小結

        本篇博客主要爲大家帶來了Oozie在實際業務場景中更常用的操作。多個任務的串聯和定時任務設置,有任何疑問可以隨時後臺聯系博主喲(^U^)ノ~YO

        如果以上過程中出現了任何的紕漏錯誤,煩請大佬們指正😅

        受益的朋友或對大數據技術感興趣的夥伴記得點贊關注支持一波🙏

在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章