工作流調度oozie

1.什麼是oozie

Oozie是運行在hadoop平臺上的一種工作流調度引擎,它可以用來調度與管理hadoop任務,如,MapReduce、Pig等。那麼,對於Oozie Workflow中的一個個的action(可以理解成一個個MapReduce任務)Oozie是根據什麼來對action的執行時間與執行順序進行管理調度的呢?其實就是我們在數據結構中常見的有向無環圖(DAGDirect Acyclic Graph)的模式來進行管理調度的,我們可以利用HPDL語言(一種xml語言)來定義整個workflow,實現工作流的調度oozie的架構以及執行流程.

注意:oozie相比於Azkaban的優點是它可以很方便的與HUE進行整合.

2.oozie的架構

在這裏插入圖片描述

  • workFlow:工作流,定義我們的工作流的任務的執行,主要由一個個的action組成,在xml中進行配置即可
  • Coordinator :協作器,就是oozie當中的定時任務調度的模塊
  • Bundle :多個Coordinator 的抽象,可以通過bundle將多個Coordinator 進行組裝集合起來,形成一個bundle 現在用的很少

3.安裝oozie

3.1 修改core-site.xml

  • 修改core-site.xml添加我們hadoop集羣的代理用戶
  		<property>
                <name>hadoop.proxyuser.hadoop.hosts</name>
                <value>*</value>
        </property>
        <property>
                <name>hadoop.proxyuser.hadoop.groups</name>
                <value>*</value>
        </property>

注意:hadoop的歷史任務的服務必須啓動,在19888端口可以查看

  • 重啓hdfs與yarn集羣以及啓動jobhistory
cd /zsc/install/hadoop-2.6.2-cdh5.14.2
sbin/stop-dfs.sh
sbin/start-dfs.sh
sbin/stop-yarn.sh
sbin/start-yarn.sh
sbin/mr-jobhistory-daemon.sh start historyserver

3.2 上傳oozie的安裝包並解壓

tar -zxvf oozie-4.1.0-cdh5.14.2.tar.gz -C  /zsc/install

3.3 解壓hadooplibs到與oozie平行的目錄

  • 將oozie-hadooplibs-4.1.0-cdh5.14.2.tar.gz 這個壓縮包,解壓到oozie的家目錄的平行目錄下
cd /zsc/install/oozie-4.1.0-cdh5.14.2
tar -zxvf oozie-hadooplibs-4.1.0-cdh5.14.2.tar.gz -C /zsc/install

3.4 創建libext目錄

  • 在oozie的安裝路徑下創建libext目錄
cd /zsc/install/oozie-4.1.0-cdh5.14.2
mkdir -p libext

3.5 拷貝依賴包到libext

cd /zsc/install/oozie-4.1.0-cdh5.14.2
cp -ra hadooplibs/hadooplib-2.6.0-cdh5.14.2.oozie-4.1.0-cdh5.14.2/* libext/
  • 拷貝mysql的驅動包
cp /zsc/install/hive-1.1.0-cdh5.14.2/lib/mysql-connector-java-5.1.38.jar /zsc/install/oozie-4.1.0-cdh5.14.2/libext/

3.6 添加ext-2.2.zip壓縮包

  • 拷貝ext-2.2.zip這個包到libext目錄當中去

3.7 修改oozie-site.xml

  • 如果沒有這些屬性,直接添加進去即可
  • oozie默認使用的是UTC的時區,我們需要在我們oozie-site.xml配置時區爲GMT+0800時區
<property>
        <name>oozie.service.JPAService.jdbc.driver</name>
        <value>com.mysql.jdbc.Driver</value>
    </property>
	
	<property>
        <name>oozie.service.JPAService.jdbc.url</name>
        <value>jdbc:mysql://node03.kaikeba.com:3306/oozie</value>
    </property>
	
	
	<property>
		<name>oozie.service.JPAService.jdbc.username</name>
		<value>root</value>
	</property>

    <property>
        <name>oozie.service.JPAService.jdbc.password</name>
        <value>123456</value>
    </property>

	<property>
			<name>oozie.processing.timezone</name>
			<value>GMT+0800</value>
	</property>


	<property>
		<name>oozie.service.ProxyUserService.proxyuser.hue.hosts</name>
        <value>*</value>
    </property>
	
	
    <property>   <name>oozie.service.ProxyUserService.proxyuser.hue.groups</name>
        <value>*</value>
    </property>
	
	<property>
        <name>oozie.service.coord.check.maximum.frequency</name>
		<value>false</value>
    </property>     


	<property>
	<name>oozie.service.HadoopAccessorService.hadoop.configurations</name>
        <value>*=/kkb/install/hadoop-2.6.0-cdh5.14.2/etc/hadoop</value>
</property>

3.8 創建mysql數據庫

# 啓動mysql服務 systemctl start mysqld.service
mysql -uroot -p
create database oozie;

3.9 上傳oozie依賴的jar包到hdfs上面去

  • 上傳oozie的解壓後目錄的yarn.tar.gz到hdfs目錄去
bin/oozie-setup.sh  sharelib create -fs hdfs://node01:8020 -locallib oozie-sharelib-4.1.0-cdh5.14.2-yarn.tar.gz

3.10 創建oozie的數據庫表

cd /zsc/install/oozie-4.1.0-cdh5.14.2
bin/oozie-setup.sh  db create -run -sqlfile oozie.sql

3.11 打包項目,生成war包

cd /zsc/install/oozie-4.1.0-cdh5.14.2
bin/oozie-setup.sh  prepare-war

3.12 配置oozie的環境變量

  • vim /etc/profile
export OOZIE_HOME=/kkb/install/oozie-4.1.0-cdh5.14.2
export OOZIE_URL=http://node03:11000/oozie
export PATH=:$OOZIE_HOME/bin:$PATH
  • source /etc/profile

3.13 啓動與關閉oozie服務

  • 啓動
cd /zsc/install/oozie-4.1.0-cdh5.14.2
bin/oozied.sh start 
  • 關閉
cd /zsc/install/oozie-4.1.0-cdh5.14.2
bin/oozied.sh stop 

3.14 瀏覽器頁面訪問oozie

  • 訪問地址 http://node03:11000/oozie/
  • 我們頁面訪問的時候,發現我們的oozie使用的還是GMT的時區,與我們現在的時區相差一定的時間,所以我們需要調整一個js的獲取時區的方法,將其改成我們現在的時區:
cd /zsc/install/oozie-4.1.0-cdh5.14.2/oozie-server/webapps/oozie
vim oozie-console.js

function getTimeZone() {
    Ext.state.Manager.setProvider(new Ext.state.CookieProvider());
    return Ext.state.Manager.get("TimezoneId","GMT+0800");
}

4.使用oozie

4.1 使用oozie調度shell腳本

oozie安裝好了之後,我們需要測試oozie的功能是否可以正常使用,官方已經給我們帶了各種測試案例,我們可以通過官方提供的各種案例來對我們的oozie進行調度.

4.1.1 解壓官方提供的調度案例

oozie自帶了各種案例,我們可以使用oozie自帶的各種案例來作爲模板,所以我們這裏先把官方提供的各種案例給解壓出來:

cd /zsc/install/oozie-4.1.0-cdh5.14.2
tar -zxf oozie-examples.tar.gz

4.1.2 創建工作目錄

在任意地方創建一個oozie的工作目錄,以後我們的調度任務的配置文件全部放到oozie的工作目錄當中去.我這裏直接在oozie的安裝目錄下面創建工作目錄.

cd /kkb/install/oozie-4.1.0-cdh5.14.2
mkdir oozie_works

4.1.3 拷貝任務模板到工作目錄當中

任務模板以及工作目錄都準備好了之後,我們把我們的shell的任務模板拷貝到我們oozie的工作目錄當中去:

cd /zsc/install/oozie-4.1.0-cdh5.14.2
cp -r examples/apps/shell/ oozie_works/

4.1.4 準備一個shell腳本

cd /kkb/install/oozie-4.1.0-cdh5.14.2
vim oozie_works/shell/hello.sh

#!/bin/bash
echo "hello world" >> /zsc/install/hello_oozie.txt

注意:這個腳本一定要是在oozie工作路徑下的shell路徑下的位置

4.1.5 修改模板下的配置文件

cd /zsc/install/oozie-4.1.0-cdh5.14.2/oozie_works/shell
vim job.properties

nameNode=hdfs://node01:8020
jobTracker=node01:8032
queueName=default
examplesRoot=oozie_works
oozie.wf.application.path=${nameNode}/user/${user.name}/${examplesRoot}/shell
EXEC=hello.sh
  • 修改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/hadoop/oozie_works/shell/${EXEC}#${EXEC}</file>

        <capture-output/>
    </shell>
    <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>

4.1.6 上傳調度任務到hdfs上面去

  • 上傳的hdfs目錄爲/user/root,因爲我們hadoop啓動的時候使用的是root用戶,如果hadoop啓動的是其他用戶,那麼就上傳到
    /user/其他用戶
cd /zsc/install/oozie-4.1.0-cdh5.14.2
hdfs dfs -put oozie_works/ /user/hadoop

4.1.7 執行調度任務

cd /zsc/install/oozie-4.1.0-cdh5.14.2
bin/oozie job -oozie http://node03:11000/oozie -config oozie_works/shell/job.properties  -run

4.2 使用oozie調度hive

4.2.1 拷貝hive的案例模板

cd /zsc/install/oozie-4.1.0-cdh5.14.2
cp -ra examples/apps/hive2/ oozie_works/

4.2.2 編輯hive模板

  • 使用的是hiveserver2來進行提交任務,需要注意我們要將hiveserver2的服務給啓動起來
  • 修改 job.properties
cd /zsc/install/oozie-4.1.0-cdh5.14.2/oozie_works/hive2
vim job.properties

nameNode=hdfs://node01:8020
jobTracker=node01:8032
queueName=default
jdbcURL=jdbc:hive2://node03:10000/default
examplesRoot=oozie_works

oozie.use.system.libpath=true
# 配置我們文件上傳到hdfs的保存路徑 實際上就是在hdfs 的/user/root/oozie_works/hive2這個路徑下
oozie.wf.application.path=${nameNode}/user/${user.name}/${examplesRoot}/hive2
  • 修改workflow.xml
<?xml version="1.0" encoding="UTF-8"?>
<workflow-app xmlns="uri:oozie:workflow:0.5" name="hive2-wf">
    <start to="hive2-node"/>

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

    <kill name="fail">
        <message>Hive2 (Beeline) action failed, error message[${wf:errorMessage(wf:lastErrorNode())}]</message>
    </kill>
    <end name="end"/>
</workflow-app>
  • 修改script.q文件
DROP TABLE IF EXISTS test;
CREATE EXTERNAL TABLE test (a INT) STORED AS TEXTFILE LOCATION '${INPUT}';
insert into test values(10);
insert into test values(20);
insert into test values(30);

4.2.3 上傳工作文件到hdfs

cd /zsc/install/oozie-4.1.0-cdh5.14.2/oozie_works
hdfs dfs -put hive2/ /user/hadoop/oozie_works/

4.2.4 執行oozie的調度

cd /zsc/install/oozie-4.1.0-cdh5.14.2
bin/oozie job -oozie http://node03:11000/oozie -config oozie_works/hive2/job.properties  -run

4.2.5 查看調度結果

在這裏插入圖片描述

4.3 oozie調度MR任務

4.3.1 準備MR執行的數據

  • 這裏通過oozie調度一個MR的程序的執行,MR的程序可以是自己寫的,也可以是hadoop工程自帶的,我們這裏就選用hadoop工程自帶的MR程序來運行wordcount的示例
  • 準備以下數據上傳到HDFS的/oozie/input路徑下去
hdfs dfs -mkdir -p /oozie/input
vim wordcount.txt
hello   world   hadoop
spark   hive    hadoop

hdfs dfs -put wordcount.txt /oozie/input

4.3.2 執行官方測試案例

yarn jar /zsc/install/hadoop-2.6.2-cdh5.14.2/share/hadoop/mapreduce/hadoop-mapreduce-examples-2.6.0-cdh5.14.2.jar wordcount /oozie/input/ /oozie/output

4.3.3 準備我們調度的資源

  • 將我們需要調度的資源都準備好放到一個文件夾下面去,包括我們的jar包,我們的job.properties,以及我們的workflow.xml
  • 拷貝MR的任務模板
cd /zsc/install/oozie-4.1.0-cdh5.14.2
cp -ra examples/apps/map-reduce/ oozie_works/
  • 刪掉MR任務模板lib目錄下自帶的jar包
cd /zsc/install/oozie-4.1.0-cdh5.14.2/oozie_works/map-reduce/lib
rm -rf oozie-examples-4.1.0-cdh5.14.2.jar

4.3.4 拷貝我們自己的jar包到對應目錄

從上一步的刪除當中,我們可以看到我們需要調度的jar包存放在了
/kkb/install/oozie-4.1.0-cdh5.14.2/oozie_works/map-reduce/lib這個目錄下,所以我們把我們需要調度的jar包也放到這個路徑下即可

cp /zsc/install/hadoop-2.6.2-cdh5.14.2/share/hadoop/mapreduce/hadoop-mapreduce-examples-2.6.0-cdh5.14.2.jar /zsc/install/oozie-4.1.0-cdh5.14.2/oozie_works/map-reduce/lib/

4.3.5 修改配置文件

  • job.properties
cd /zsc/install/oozie-4.1.0-cdh5.14.2/oozie_works/map-reduce
vim job.properties
nameNode=hdfs://node01:8020
jobTracker=node01:8032
queueName=default
examplesRoot=oozie_works

oozie.wf.application.path=${nameNode}/user/${user.name}/${examplesRoot}/map-reduce/workflow.xml
outputDir=/oozie/output
inputdir=/oozie/input
  • workflow.xml
cd /zsc/install/oozie-4.1.0-cdh5.14.2/oozie_works/map-reduce
vim workflow.xml
<?xml version="1.0" encoding="UTF-8"?>
<!--
  Licensed to the Apache Software Foundation (ASF) under one
  or more contributor license agreements.  See the NOTICE file
  distributed with this work for additional information
  regarding copyright ownership.  The ASF licenses this file
  to you under the Apache License, Version 2.0 (the
  "License"); you may not use this file except in compliance
  with the License.  You may obtain a copy of the License at
  
       http://www.apache.org/licenses/LICENSE-2.0
  
  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.
-->
<workflow-app xmlns="uri:oozie:workflow:0.5" name="map-reduce-wf">
    <start to="mr-node"/>
    <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="end"/>
        <error to="fail"/>
    </action>
    <kill name="fail">
        <message>Map/Reduce failed, error message[${wf:errorMessage(wf:lastErrorNode())}]</message>
    </kill>
    <end name="end"/>
</workflow-app>

4.3.6 執行調度任務

# 上傳到HDFS
cd /zsc/install/oozie-4.1.0-cdh5.14.2/oozie_works
hdfs dfs -put map-reduce/ /user/hadoop/oozie_works/

cd /zsc/install/oozie-4.1.0-cdh5.14.2
bin/oozie job -oozie http://node03:11000/oozie -config oozie_works/map-reduce/job.properties -run

4.4 oozie的任務串聯

在實際工作當中,肯定會存在多個任務需要執行,並且存在上一個任務的輸出結果作爲下一個任務的輸入數據這樣的情況,所以我們需要在workflow.xml配置文件當中配置多個action,實現多個任務之間的相互依賴關係
需求:首先執行一個shell腳本,執行完了之後再執行一個MR的程序,最後再執行一個hive的程序

4.4.1 準備工作目錄

cd /zsc/install/oozie-4.1.0-cdh5.14.2/oozie_works
mkdir -p sereval-actions

4.4.2 準備調度文件

將之前的hive,shell,以及MR的執行,進行串聯成到一個workflow當中去,準備資源文件:

cd /kkb/install/oozie-4.1.0-cdh5.14.2/oozie_works
cp hive2/script.q sereval-actions/
cp shell/hello.sh sereval-actions/
cp -ra map-reduce/lib sereval-actions/

4.4.3 開發調度的配置文件

  • 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/hadoop/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
nameNode=hdfs://node01:8020
jobTracker=node01: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

4.4.4 執行調度任務

cd /zsc/install/oozie-4.1.0-cdh5.14.2/oozie_works/
hdfs dfs -put sereval-actions/ /user/hadoop/oozie_works/
cd /zsc/install/oozie-4.1.0-cdh5.14.2/
bin/oozie job -oozie http://node03:11000/oozie -config oozie_works/serveral-actions/job.properties -run

4.5 oozie的定時任務執行

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

  • 基於時間的定時任務調度,oozie基於時間的調度主要需要指定三個參數,第一個起始時間,第二個結束時間,第三個調度頻率
  • 基於數據的任務調度,只有在有了數據纔會去出發執行 這種是基於數據的調度,只要在有了數據纔會觸發調度任務

4.5.1 oozie當中定時任務的設置

  • 拷貝定時任務的調度模板
cd /zsc/install/oozie-4.1.0-cdh5.14.2
cp -r examples/apps/cron oozie_works/cron-job
  • 拷貝hello.sh腳本
cd /kkb/install/oozie-4.1.0-cdh5.14.2/oozie_works
cp shell/hello.sh  cron-job/
  • job.properties
cd /zsc/install/oozie-4.1.0-cdh5.14.2/oozie_works/cron-job
vim job.properties
nameNode=hdfs://node01:8020
jobTracker=node01:8032
queueName=default
examplesRoot=oozie_works

oozie.coord.application.path=${nameNode}/user/${user.name}/${examplesRoot}/cron-job/coordinator.xml
start=2018-08-22T19:20+0800
end=2019-08-22T19:20+0800
EXEC=hello.sh
workflowAppUri=${nameNode}/user/${user.name}/${examplesRoot}/cron-job/workflow.xml
  • 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
<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/hadoop/oozie_works/cron-job/${EXEC}#${EXEC}</file>

        <capture-output/>
    </shell>
    <ok to="end"/>
    <error to="end"/>
</action>
    <end name="end"/>
</workflow-app>

4.5.2 oozie任務查看

  • 查看所有普通任務
    oozie jobs
  • 查看定時任務
    oozie jobs -jobtype coordinator
  • 殺死某個任務
    oozie可以通過jobid來殺死某個定時任務
oozie job -kill [id]
例如我們可以使用命令
oozie job -kill 0000085-180628150519513-oozie-root-C
來殺死我們定時任務

5.HUE整合oozie

  • 停止oozie與hue的進程 bin/oozied.sh stop
  • 修改hue的配置文件
# The URL where the Oozie service runs on. This is required in order for
  # users to submit jobs. Empty value disables the config check.
  oozie_url=http://node03.hadoop.com:11000/oozie

  # Requires FQDN in oozie_url if enabled
  ## security_enabled=false

  # Location on HDFS where the workflows/coordinator are deployed when submitted.
  remote_deployement_dir=/user/hadoop/oozie_works
  • 修改oozie的配置文件
# Location on local FS where the examples are stored.
  # local_data_dir=/kkb/install/oozie-4.1.0-cdh5.14.2/examples/apps

  # Location on local FS where the data for the examples is stored.
  # sample_data_dir=/kkb/install/oozie-4.1.0-cdh5.14.2/examples/input-data

  # Location on HDFS where the oozie examples and workflows are stored.
  # Parameters are $TIME and $USER, e.g. /user/$USER/hue/workspaces/workflow-$TIME
  # remote_data_dir=/user/root/oozie_works/examples/apps

  # Maximum of Oozie workflows or coodinators to retrieve in one API call.
  oozie_jobs_count=100

  # Use Cron format for defining the frequency of a Coordinator instead of the old frequency number/unit.
  enable_cron_scheduling=true

  # Flag to enable the saved Editor queries to be dragged and dropped into a workflow.
  enable_document_action=true

  # Flag to enable Oozie backend filtering instead of doing it at the page level in Javascript. Requires Oozie 4.3+.
  enable_oozie_backend_filtering=true

  # Flag to enable the Impala action.
  enable_impala_action=true
  • filebrowser
  # Location on local filesystem where the uploaded archives are temporary stored.
  archive_upload_tempdir=/tmp

  # Show Download Button for HDFS file browser.
  show_download_button=true

  # Show Upload Button for HDFS file browser.
  show_upload_button=true

  # Flag to enable the extraction of a uploaded archive in HDFS.
  enable_extract_uploaded_archive=true

6.oozie使用過程中可能遇到的問題

  • Mysql權限配置:授權所有主機可以使用root用戶操作所有數據庫和數據表
mysql> grant all on *.* to root@'%' identified by '123456' with grant option;
mysql> flush privileges;
mysql> exit;
  • workflow.xml配置的時候不要忽略file屬性
  • jps查看進程時,注意有沒有bootstrap
  • 關閉oozie.如果bin/oozied.sh stop無法關閉,則可以使用kill -9 [pid],之後oozie根目錄下的oozie-server/temp/xxx.pid文件一定要刪除。
  • Oozie重新打包時,一定要注意先關閉進程,刪除對應文件夾下面的pid文件
  • 配置文件一定要生效.起始標籤和結束標籤無對應則不生效,配置文件的屬性寫錯了,那麼則執行默認的屬性
  • libext下邊的jar存放於某個文件夾中,導致share/lib創建不成功。
  • 修改Hadoop配置文件,需要重啓集羣。一定要記得scp到其他節點。
  • JobHistoryServer必須開啓,集羣要重啓的。
  • Mysql配置如果沒有生效的話,默認使用derby數據庫。
  • 在本地修改完成的job配置,必須重新上傳到HDFS。
  • 將HDFS中上傳的oozie配置文件下載下來查看是否有錯誤
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章