Apache Oozie 5.2.1 Workflow 与 Coordinator 实战详解

Apache Oozie 5.2.1 实战:workflow.xml 节点与 EL 函数、job.properties 参数化、map-reduce action 全链路实测(HDFS 准备/提交/轮询/SUCCEEDED)、coordinator cron 定时调度验证、bundle 概念与常用 CLI 命令速查

Apache OozieOozieApache工作流调度Hadoop大数据2026/10/15

Apache Oozie 5.2.1 Workflow 与 Coordinator 实战详解

目标:在已运行的 Oozie 5.2.1 上完成一次完整的 workflow(map-reduce action)提交与轮询、一次 coordinator(cron 定时)调度验证,并沉淀 job.properties 参数化、EL 函数、CLI 命令速查与错误排查方法。全部命令与回显均在 Ubuntu 22.04 + Oozie 5.2.1 + Hadoop 3.3.6 伪分布式实测:workflow 0000000-261014183638552-oozie-root-W 与 coordinator 0000001-261014183638552-oozie-root-C 均达 SUCCEEDED。

一、环境信息

本文所有命令与回显均在以下环境实测采集。

项目值
操作系统Ubuntu 22.04(主机名 oozie,内网 IP 172.17.0.15)
Oozie5.2.1(源码构建 -Phadoop-3 -Dhadoop.version=3.3.6,安装于 /opt/oozie-5.2.1,端口 11000)
Hadoop3.3.6 伪分布式(/opt/hadoop,NameNode hdfs://oozie:9000,ResourceManager oozie:8032)
sharelibHDFS /user/root/share/lib/lib_20261014181925
示例包发行包自带 oozie-examples.tar.gz(含 map-reduce / no-op / cron-schedule 示例)
关键环境变量OOZIE_URL=http://localhost:11000/oozie、JAVA_HOME=/usr/lib/jvm/java-8-openjdk-amd64
实测结果workflow 0000000-261014183638552-oozie-root-W SUCCEEDED(耗时约 1 分钟);coordinator 0000001-261014183638552-oozie-root-C SUCCEEDED

💡 说明:Oozie 服务(oozied.sh start)、Hadoop(start-dfs.sh/start-yarn.sh)与 sharelib 上传需先就绪;本文第二章给出一分钟健康自检。作业 ID 中 oozie-root 来自 oozie.system.id,W/C 后缀分别代表 Workflow/Coordinator 类型。

二、前置条件与示例准备

本章确认 Oozie 服务健康,并把发行包自带的示例上传到 HDFS,为后续 workflow/coordinator 实战备好材料。

2.1 服务健康自检

export OOZIE_URL=http://localhost:11000/oozie
export JAVA_HOME=/usr/lib/jvm/java-8-openjdk-amd64
/opt/oozie-5.2.1/bin/oozie admin -status

实测回显:

System mode: NORMAL

System mode: NORMAL 即服务可接受提交。若命令报连接失败,先确认 oozied.sh start 已执行、11000 端口可访问(curl -s http://localhost:11000/oozie/v2/admin/status 应返回 {"systemMode":"NORMAL"})。

2.2 解压示例并上传 HDFS

cd /opt/oozie-5.2.1 && tar -xzf oozie-examples.tar.gz
/opt/hadoop/bin/hdfs dfs -mkdir -p /user/root
/opt/hadoop/bin/hdfs dfs -put -f /opt/oozie-5.2.1/examples /user/root/

上传后核验(实测回显):

/opt/hadoop/bin/hdfs dfs -ls /user/root/examples/apps/map-reduce
Found 5 items
-rw-r--r--   1 root supergroup       1033 2026-10-14 18:31 /user/root/examples/apps/map-reduce/job-with-config-class.properties
-rw-r--r--   1 root supergroup        233 2026-10-14 18:31 /user/root/examples/apps/map-reduce/job.properties
drwxr-xr-x   - root supergroup          0 2026-10-14 18:31 /user/root/examples/apps/map-reduce/lib
-rw-r--r--   1 root supergroup       2289 2026-10-14 18:31 /user/root/examples/apps/map-reduce/workflow-with-config-class.xml
-rw-r--r--   1 root supergroup       2574 2026-10-14 18:31 /user/root/examples/apps/map-reduce/workflow.xml

要点:lib/ 内含 oozie-examples-5.2.1.jar(示例的 SampleMapper/SampleReducer 就在其中),Oozie 约定应用目录下的 lib/ 会自动加入作业 classpath;examples/input-data/text 目录自带莎士比亚文本,是 map-reduce 示例的默认输入。

2.3 环境变量汇总

后续所有命令基于以下三件套(每台执行机只需设置一次,写入 /root/.bashrc 可持久化):

变量值作用
OOZIE_URLhttp://localhost:11000/oozieoozie CLI 的默认服务端地址,免于每次 -oozie 指定
JAVA_HOME/usr/lib/jvm/java-8-openjdk-amd64oozie/hadoop 脚本启动 JVM 的依据
工作目录/opt/oozie-5.2.1/examples/apps/map-reducejob.properties 所在目录(提交时 -config 用相对路径)

三、Workflow 定义详解

Workflow 是 Oozie 的核心编排单元:一个以 DAG 组织的节点图,定义在 HDFS 的 workflow.xml 中。本章先讲结构,再用实测文件逐段拆解。

3.1 结构总览

workflow.xml 的骨架:根元素 <workflow-app name="..." xmlns="uri:oozie:workflow:1.0">,内部由「控制节点 + 动作节点」构成有向图,每个节点通过 <ok to="..."/> 与 <error to="..."/> 声明成功/失败两条去向。schema 版本 1.0 是 5.x 的主用版本;注意 1.0 schema 的 map-reduce action 用 <resource-manager> 元素(不再是 4.x 的 <job-tracker>)。

控制节点与动作节点速览:

节点类别作用
<start to="node"/>控制入口,指定首个执行节点
<end name="node"/>控制成功终点
<kill name="node"><message>…</message></kill>控制失败终点,message 支持 EL,状态置 KILLED
<decision name="node"><switch><case expr="EL"/>…<default/></switch></decision>控制多条件分支,取第一个为真的 case
<fork name="node"> / <join name="node"/>控制并行开叉与汇合(join 前各分支全部成功才继续)
<action name="node">…</action>动作执行 map-reduce/fs/java/hive2/pig/sqoop/spark/shell/email/sub-workflow 等任务

3.2 实测 workflow.xml 原文与逐段解读

发行包 examples 的 map-reduce 应用(/user/root/examples/apps/map-reduce/workflow.xml,实测原文):

<workflow-app xmlns="uri:oozie:workflow:1.0" name="map-reduce-wf">
    <start to="mr-node"/>
    <action name="mr-node">
        <map-reduce>
            <resource-manager>${resourceManager}</resource-manager>
            <name-node>${nameNode}</name-node>
            <prepare>
                <delete path="${nameNode}/user/${wf:user()}/${examplesRoot}/output-data/${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>
            </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>

逐段解读:

片段含义
<start to="mr-node"/>入口直达唯一的动作节点 mr-node
<resource-manager>${resourceManager}</resource-manager>YARN RM 地址,由 job.properties 注入(实测 oozie:8032)
<name-node>${nameNode}</name-node>HDFS 地址(实测 hdfs://oozie:9000)
<prepare><delete path="…"/></prepare>action 执行前的 HDFS 预处理:删除旧输出目录,保证作业可重跑
<configuration>传给底层 MapReduce 作业的参数:队列名、Mapper/Reducer 类、map 任务数、输入/输出目录
${wf:user()}运行期 EL:取提交用户(实测解析为 root),用于拼出 /user/root/… 路径
<ok to="end"/> / <error to="fail"/>成功去终点;失败去 kill 节点
<kill> 的 message${wf:errorMessage(wf:lastErrorNode())} 取最后一个失败节点的错误信息,进日志与 UI

3.3 Workflow 生命周期状态

一个 workflow 作业实例的状态流转(官方定义,实测可观察到其中大部分):

状态含义实测观察点
PREP已创建未启动提交瞬间瞬时状态
RUNNING节点流转中oozie job -info 的 Status 列
SUSPENDED挂起(可恢复)oozie job -suspend/-resume 触发
SUCCEEDED成功结束实测 0000000-…-W 终态
KILLED被终止实测卡 PREP 的失败作业被 -kill 后进入
FAILED执行失败action error 转移触发

动作(action)另有独立状态:PREP → RUNNING → OK/ERROR/…(oozie job -info 下半表逐动作展示,含 Ext ID 与 Err Code 列)。

四、job.properties 参数化

job.properties 是提交侧的纯键值参数文件:既承载 workflow 引用的业务变量,也承载 Oozie 的指令型键(应用路径、sharelib 开关等)。它只存在于提交客户端,不上传 HDFS——这也是「workflow.xml 上 HDFS、job.properties 留本地」的分工。

4.1 实测文件原文

/opt/oozie-5.2.1/examples/apps/map-reduce/job.properties(实测原文,全部落实际值):

nameNode=hdfs://oozie:9000
resourceManager=oozie:8032
queueName=default
examplesRoot=examples
oozie.use.system.libpath=true
oozie.wf.application.path=${nameNode}/user/${user.name}/${examplesRoot}/apps/map-reduce
outputDir=map-reduce

4.2 逐项说明

键实测值说明
nameNodehdfs://oozie:9000注入 workflow 的 <name-node>;与 core-site.xml 的 fs.defaultFS 一致
resourceManageroozie:8032注入 <resource-manager>;与 yarn.resourcemanager.hostname 对应
queueNamedefault注入 mapred.job.queue.name,作业提交到的 YARN 队列
examplesRootexamples示例根目录名,配合 ${wf:user()} 拼 HDFS 路径
oozie.use.system.libpathtrue提交时自动加载 HDFS 系统 sharelib(/user/root/share/lib/lib_…)
oozie.wf.application.path${nameNode}/user/${user.name}/${examplesRoot}/apps/map-reduce指令键:workflow 应用在 HDFS 的路径(目录,内含 workflow.xml 与 lib/)
outputDirmap-reduce输出子目录名,注入 <prepare> 与 mapred.output.dir

关键规则:oozie.wf.application.path(workflow)/ oozie.coord.application.path(coordinator)/ oozie.bundle.application.path(bundle)分别指明三类应用在 HDFS 的位置;${user.name} 取当前系统用户,与 ${wf:user()} 一致,因此 HDFS 上目录必须位于 /user/<提交用户>/ 下(2.2 已把 examples 放到 /user/root/)。

4.3 修改参数的实操方式

换输出目录、换队列等场景直接编辑本地 job.properties 再提交即可;临时替换用 oozie job -config job.properties -run 提交前先改文件(CLI 不支持逐键覆盖)。把示例复制一份自用时,记得同步改 oozie.wf.application.path 指向新的 HDFS 目录,并把该目录整体(workflow.xml + lib/)上传。

五、map-reduce action 实战全链路

本章把 3.2/4.1 的示例应用完整跑一遍:准备 → 提交 → 轮询 → 验证输出,全程实测回显。执行目录为 /opt/oozie-5.2.1/examples/apps/map-reduce(job.properties 所在处)。

5.1 输入数据确认

示例输入随发行包自带(/user/root/examples/input-data/text,莎士比亚文本,随 2.2 一并上传)。确认存在:

/opt/hadoop/bin/hdfs dfs -ls /user/root/examples/input-data/text

(输出节选,实测要点:目录下有若干 .txt 文件,SampleMapper 按行切分输出词组,SampleReducer 原样聚合。)

5.2 提交作业

cd /opt/oozie-5.2.1/examples/apps/map-reduce
/opt/oozie-5.2.1/bin/oozie job -config job.properties -run

实测回显:

job: 0000000-261014183638552-oozie-root-W

回显即作业 ID(-run 异步提交,立刻返回)。服务端收到后:解析 workflow.xml → 写 WF_JOBS 表 → 起始节点 → 对 mr-node 向 YARN 提交 launcher 作业。

⚠️ 说明:本环境前两次提交(0000000-261014182944353-oozie-root-W、0000000-261014183327602-oozie-root-W)因服务端缺 YARN 客户端 jar 卡在 PREP,补齐依赖(见 9.2)重启后第三次提交成功——若你也是首次部署,提交卡住先看第九章。

5.3 轮询 job -info 直至 SUCCEEDED

/opt/oozie-5.2.1/bin/oozie job -info 0000000-261014183638552-oozie-root-W

提交后约 75 秒的实测回显(终态):

Job ID : 0000000-261014183638552-oozie-root-W
------------------------------------------------------------------------------------------------------------------------------------
Workflow Name : map-reduce-wf
App Path      : hdfs://oozie:9000/user/root/examples/apps/map-reduce
Status        : SUCCEEDED
Run           : 0
User          : root
Group         : -
Created       : 2026-10-14 18:36 GMT
Started       : 2026-10-14 18:36 GMT
Last Modified : 2026-10-14 18:37 GMT
Ended         : 2026-10-14 18:37 GMT
CoordAction ID: -
Actions
------------------------------------------------------------------------------------------------------------------------------------
ID                                                                            Status    Ext ID                 Ext Status Err Code
------------------------------------------------------------------------------------------------------------------------------------
0000000-261014183638552-oozie-root-W@:start:                                  OK        -                      OK         -
------------------------------------------------------------------------------------------------------------------------------------
0000000-261014183638552-oozie-root-W@mr-node                                  OK        application_1791998675123_0003SUCCEEDED  -
------------------------------------------------------------------------------------------------------------------------------------
0000000-261014183638552-oozie-root-W@end                                      OK        -                      OK         -
------------------------------------------------------------------------------------------------------------------------------------

读表要点:上半表是作业级信息(Status=SUCCEEDED、User=root、App Path 与 oozie.wf.application.path 一致);下半表逐动作展示——mr-node 的 Ext ID application_1791998675123_0003 是 YARN 上的 launcher/业务作业,Ext Status=SUCCEEDED 即底层作业成功,Err Code=- 表示无错误码。轮询期间 Status 会经历 RUNNING、动作从 PREP→RUNNING→OK。

5.4 服务端日志关键段

/opt/oozie-5.2.1/bin/oozie job -log 0000000-261014183638552-oozie-root-W

关键日志段(输出节选,实测):

2026-10-14 18:36:53,533  INFO ActionStartXCommand:520 - SERVER[oozie] USER[root] GROUP[-] TOKEN[] APP[map-reduce-wf]
 JOB[0000000-261014183638552-oozie-root-W] ACTION[...-W@mr-node] Start action [...-W@mr-node] with user-retry state :
 userRetryCount [0], userRetryMax [0], userRetryInterval [10]
2026-10-14 18:36:53,537  INFO MapReduceActionExecutor:520 - ... ACTION[...-W@mr-node] Starting action. Getting Action File System
2026-10-14 18:36:53,622  WARN MapReduceActionExecutor:523 - ... Invalid configuration value [null] defined for launcher max attempts count, using default [2].
2026-10-14 18:36:54,386  INFO MapReduceActionExecutor:520 - ... checking action, hadoop job ID [application_1791998675123_0003] status [RUNNING]
2026-10-14 18:36:54,390  INFO ActionStartXCommand:520 - ... ACTION[...-W@mr-node] Action status=RUNNING
(……launcher MR 作业在 YARN 上执行……)
2026-10-14 18:37:40,035  INFO ActionStartXCommand:520 - ... ACTION[...-W@end] Action status=DONE
2026-10-14 18:37:40,059  INFO EndActionExecutor:520 - ... ACTION[...-W@end] Action ended with external status [OK]

要点:user-retry 是动作级用户重试计数(默认不重试);launcher max attempts 默认 2;checking action, hadoop job ID […] status [RUNNING] 体现了「服务端轮询 YARN 作业」的调度闭环。

5.5 输出数据验证

workflow 的 <prepare> 先删后写,成功后输出目录应有 _SUCCESS 标记与 part 文件(实测回显):

/opt/hadoop/bin/hdfs dfs -ls /user/root/examples/output-data/map-reduce/
Found 2 items
-rw-r--r--   1 root supergroup          0 2026-10-14 18:37 /user/root/examples/output-data/map-reduce/_SUCCESS
-rw-r--r--   1 root supergroup       1547 2026-10-14 18:37 /user/root/examples/output-data/map-reduce/part-00000
/opt/hadoop/bin/hdfs dfs -cat /user/root/examples/output-data/map-reduce/part-00000 | head -3
0       To be or not to be, that is the question;
42      Whether 'tis nobler in the mind to suffer
84      The slings and arrows of outrageous fortune,

_SUCCESS 文件 + 分行文本(行号 + 原句)即为 SampleMapper/SampleReducer 的预期输出,全链路验证通过。

5.6 元数据落库验证(可选)

mysql -uoozie -poozie123 -h127.0.0.1 -P3306 -e "SELECT COUNT(*) AS wf_jobs FROM oozie.WF_JOBS;"

实测本环境累计提交 3 次 map-reduce(含两次失败的)加 1 个 coordinator 触发的 no-op 实例:

wf_jobs
4

六、Coordinator 定时调度实战

Coordinator 在 workflow 之上叠加「周期触发」:按 frequency 把 start~end 时间区间切成一个个 nominal time,逐个实体化(materialize)动作并触发 workflow 实例。本章用发行包自带的 cron-schedule + no-op 示例实测 cron 频率调度闭环。

💡 技术拓展:Coordinator 的「频率表达」有两种形式——

形式写法特点适用场景
frequency + timeunitfrequency="60"(配 minute/hour/day 等时间单元)从 start 起算的等间隔周期简单固定周期任务
cron 表达式(0.2+ schema)frequency="0 0 1 * *"可表达「每天 1 点」等锚定时刻,timezone 必填日报/跨时区精确调度

本章实测采用 cron 形式(0/10 * * * *,每 10 分钟一个 nominal time,timezone="UTC")。

6.1 被调度对象:no-op workflow

cron-schedule 示例不直接跑 MR,而是调度发行包的 no-op 应用(examples/apps/no-op,一个 start → end 空跑 workflow,秒级完成,专用于验证调度闭环)。确认其已在 HDFS(2.2 已随 examples 整体上传):

/opt/hadoop/bin/hdfs dfs -ls /user/root/examples/apps/no-op

(输出节选,实测要点:目录含 workflow.xml,无 lib/,因为 no-op 无业务依赖。)

6.2 coordinator.xml 实测原文与解读

/user/root/examples/apps/cron-schedule/coordinator.xml(发行包原文,0.2 schema):

<coordinator-app name="cron-coord" frequency="0/10 * * * *" start="${start}" end="${end}" timezone="UTC"
                 xmlns="uri:oozie:coordinator:0.2">
    <action>
        <workflow>
            <app-path>${workflowAppUri}</app-path>
            <configuration>
                <property><name>resourceManager</name><value>${resourceManager}</value></property>
                <property><name>nameNode</name><value>${nameNode}</value></property>
                <property><name>queueName</name><value>${queueName}</value></property>
            </configuration>
        </workflow>
    </action>
</coordinator-app>

逐项解读:

片段含义
frequency="0/10 * * * *"cron 频率:每 10 分钟一个触发点(0.2+ schema 支持 cron)
start="${start}" end="${end}"实体化区间起止,由 job.properties 注入;区间外的 nominal time 不生成动作
timezone="UTC"cron 频率下必填;nominal time 按此时区生成(实测日志与 info 输出均为 GMT 显示)
<action><workflow><app-path>每个触发点要启动的 workflow 应用路径(实测指向 no-op)
<configuration>向被调 workflow 透传参数(resourceManager/nameNode/queueName),相当于替 workflow 准备 job.properties 中的业务键

💡 说明:除时间触发外,Coordinator 还支持 dataset(数据集)+ 初始实例的数据可用性触发——在 coordinator.xml 中声明 <datasets>(HDFS 上按 ${YEAR}${MONTH}${DAY} 等模板分区的时间序列目录)与 <input-events><data-in>,数据实例就绪才触发;时间与数据两类触发可组合。该模型属官方 CoordinatorFunctionalSpec 定义,本章实测走 cron 路线,数据触发使用时以官方规范为准。

6.3 提交参数(cron-coord.properties)

提交参数文件 /opt/oozie-5.2.1/cron-coord.properties(实测原文):

nameNode=hdfs://oozie:9000
resourceManager=oozie:8032
queueName=default
workflowAppUri=${nameNode}/user/root/examples/apps/no-op
start=2026-10-14T18:40Z
end=2026-10-14T18:50Z
oozie.coord.application.path=${nameNode}/user/root/examples/apps/cron-schedule

逐项说明:workflowAppUri 注入 coordinator.xml 的 <app-path>(no-op 应用);start/end 用 ISO 时间并带 Z(UTC,与 timezone 一致),实测区间 18:40~18:50 共 10 分钟;oozie.coord.application.path 是 coordinator 应用的 HDFS 路径(指令键,指向 cron-schedule 目录)。

6.4 提交与轮询

/opt/oozie-5.2.1/bin/oozie job -config /opt/oozie-5.2.1/cron-coord.properties -run

实测回显:

job: 0000001-261014183638552-oozie-root-C

注意 ID 尾缀为 C(Coordinator 类型)。约 110 秒后查询:

/opt/oozie-5.2.1/bin/oozie job -info 0000001-261014183638552-oozie-root-C

实测回显(终态):

Job ID : 0000001-261014183638552-oozie-root-C
------------------------------------------------------------------------------------------------------------------------------------
Job Name    : cron-coord
App Path    : hdfs://oozie:9000/user/root/examples/apps/cron-schedule
Status      : SUCCEEDED
Start Time  : 2026-10-14 18:40 GMT
End Time    : 2026-10-14 18:50 GMT
Pause Time  : -
Concurrency : 1
------------------------------------------------------------------------------------------------------------------------------------
ID                                         Status    Ext ID                               Err Code  Created              Nominal Time
------------------------------------------------------------------------------------------------------------------------------------
0000001-261014183638552-oozie-root-C@1     SUCCEEDED 0000002-261014183638552-oozie-root-W -         2026-10-14 18:39 GMT 2026-10-14 18:40 GMT
------------------------------------------------------------------------------------------------------------------------------------

读表要点:区间 18:40~18:50(UTC)内按 0/10 * * * * 只落了 18:40 一个 nominal time,对应动作 C@1;该动作 SUCCEEDED,其 Ext ID 0000002-261014183638552-oozie-root-W 指向它触发的 workflow 实例(no-op)——这就是 coordinator→workflow 的实例化证据。Concurrency=1 表示同一时刻最多 1 个实例并发执行。

6.5 Coordinator 生命周期要点

与 workflow 类似,coordinator 作业状态含 PREP/RUNNING/SUCCEEDED/KILLED/FAILED 等(长周期任务会长期 RUNNING,到 end 后按所有动作结果落终态);实体化出的动作存于 COORD_ACTIONS 表。暂停/恢复用 oozie job -suspend <id> / oozie job -resume <id>;改触发参数需重新提交(Coordinator 定义不支持运行期修改 frequency)。实测本环境 SELECT COUNT(*) FROM oozie.COORD_JOBS; 返回 1。

七、Bundle 说明

Bundle 是三层模型的顶层:把多个 coordinator 聚合成一个作业统一提交与管控(统一挂起/恢复/终止、统一 kick-off 时间)。本章为结构说明与提交形态(依据发行包 bundle 示例与官方 DG_Bundle 记录,未做运行实测);运行行为与 coordinator 同源(Bundle Job 状态见 BUNDLE_JOBS 表,本环境建库后即存在该表)。

7.1 bundle.xml 结构

(结构示意,取自官方示例形态)

<bundle-app name="bundle-name" xmlns="uri:oozie:bundle:0.2">
    <controls>
        <kick-off-time>${kickoffTime}</kick-off-time>
    </controls>
    <coordinator name="coord-1">
        <app-path>${nameNode}/user/root/examples/apps/cron-schedule</app-path>
        <configuration>
            <property><name>start</name><value>${start}</value></property>
            <property><name>end</name><value>${end}</value></property>
            <property><name>workflowAppUri</name><value>${workflowAppUri}</value></property>
        </configuration>
    </coordinator>
</bundle-app>

结构要点:<controls><kick-off-time> 控制整包最早启动时间;每个 <coordinator> 子块指向一个 coordinator 应用(app-path),<configuration> 为其注入缺失参数(如 start/end)——即「bundle 提供参数、coordinator 补齐自身、workflow 干活」的参数接力。

7.2 提交命令形态

与 workflow/coordinator 完全一致(job.properties 中用 oozie.bundle.application.path 指明 bundle 应用 HDFS 路径):

/opt/oozie-5.2.1/bin/oozie job -config bundle.properties -run

提交后返回 job: 000000X-…-oozie-root-B(尾缀 B),随后 oozie job -info <id> 可见其下属 coordinator 的实时状态。

八、oozie CLI 命令速查

本章汇总实测过的 oozie CLI 子命令,命令与回显均来自本文环境。所有命令默认依赖 OOZIE_URL(2.3),也可用 -oozie <url> 显式指定。

8.1 命令总览

命令用途实测结果
oozie admin -status服务健康检查返回 System mode: NORMAL
oozie job -config <file> -run提交 workflow/coordinator/bundle返回作业 ID
oozie job -info <id>查看作业状态与动作明细见 5.3/6.4 实测回显
oozie job -log <id>查看作业服务端日志见 5.4
oozie job -kill <id>终止作业见 8.5
-suspend / -resume <id>挂起/恢复长周期作业机制说明(本文未实测)

8.2 提交:job -run

/opt/oozie-5.2.1/bin/oozie job -config job.properties -run
job: 0000000-261014183638552-oozie-root-W

coordinator 提交同形(-config /opt/oozie-5.2.1/cron-coord.properties -run,返回 …-C ID)。-run 用于即时提交;长周期 coordinator 也可用 -start 显式启动 PREP 态作业。

8.3 查询:job -info 与 job -log

-info 见 5.3(workflow 终态全表)与 6.4(coordinator 终态全表);-log 见 5.4。二者的动作明细列(Status/Ext ID/Ext Status/Err Code)是排障第一入口。

8.4 服务端管理:admin -status 与 REST

/opt/oozie-5.2.1/bin/oozie admin -status
System mode: NORMAL
curl -s http://localhost:11000/oozie/v2/admin/status
{"systemMode":"NORMAL"}

REST 前缀为 /oozie/v2/,-info/-log 等均有对应 REST 路径(如 /v2/job/<id>),适合脚本化巡检。

8.5 终止:job -kill

对卡住的作业(见 9.1 的 PREP 现场)执行:

/opt/oozie-5.2.1/bin/oozie job -kill 0000000-261014182944353-oozie-root-W

实测回显:

job: 0000000-261014182944353-oozie-root-W killed

九、错误排查与常见问题

本章沉淀实测遇到的失败现场、通用排查路径与官方错误码口径。

9.1 实测失败现场:作业卡在 PREP

现象:服务端缺 YARN 客户端 jar 时提交,oozie job -info 显示作业 Status 为 RUNNING 但 mr-node 动作长期 PREP、Ext ID 始终为 -(实测回显):

Status        : RUNNING
ID                                                                            Status    Ext ID                 Ext Status Err Code
0000000-261014182944353-oozie-root-W@mr-node                                  PREP      -                      -          -

服务端日志(oozie job -log / logs/oozie.log)中出现根因(实测回显):

2026-10-14 18:31:14,998 ERROR ActionStartXCommand:517 - SERVER[oozie] USER[root] GROUP[-] TOKEN[] APP[map-reduce-wf]
 JOB[0000000-261014182944353-oozie-root-W] ACTION[...-W@mr-node] Error,
Caused by: java.lang.ClassNotFoundException: org.apache.hadoop.yarn.client.api.YarnClient

处置:oozie job -kill <id> 终止该作业(回显见 8.5)→ 补齐服务端 jar → 重启 Oozie → 重新提交。本环境的完整补齐链条见 9.2。

9.2 服务端缺 jar 的补齐链条(自包含要点)

三连环缺 jar 的根因相同:-Phadoop-3 构建的 Oozie webapp 只声明了 hadoop-common/hdfs-client,对 Hadoop 3.3.6 客户端依赖不全。按顺序补齐(lib/ 与 embedded-oozie-server/webapp/WEB-INF/lib/ 两处都要有,逐条执行后重启 Oozie):

报错(服务端日志)补齐的 jar(来源 /opt/hadoop/share/)
ClassNotFoundException: com.mysql.cj.jdbc.Drivermysql-connector-j-8.0.33.jar(下载目录)
NoClassDefFoundError: org/apache/hadoop/mapred/JobConfhadoop/mapreduce/hadoop-mapreduce-client-core-3.3.6.jar
ClassNotFoundException: org.apache.hadoop.yarn.client.api.YarnClienthadoop/yarn/hadoop-yarn-client-3.3.6.jar + hadoop/mapreduce/hadoop-mapreduce-client-{common,jobclient,app,hs}-3.3.6.jar
NoClassDefFoundError: org/eclipse/jetty/websocket/api/WebSocketExceptionhadoop/yarn/lib/websocket-*.jar(5 个,9.4.51)

重启顺序:oozied.sh stop → rm -f /opt/oozie-5.2.1/embedded-oozie-server/oozie.pid(清理残留 PID)→ oozied.sh start → oozie admin -status 确认 NORMAL → 重新提交作业。

9.3 错误码口径与通用排查路径

实测说明:本环境遇到的问题(卡 PREP、服务启动失败)在 oozie job -info 的 Err Code 列均显示 -——Oozie 不少运行期故障并不落在错误码上,而是以服务端日志异常呈现,因此排障第一步永远是 oozie job -log <id> 与服务端 oozie.log。

官方错误码体系中与 workflow 定义直接相关的一组(WorkflowFunctionalSpec 附录定义,workflow.xml 解析/求值错误会落到 Err Code 列):

错误码官方含义
E0700XML error(workflow.xml 解析失败)
E0701XML schema issue(不符合 schema 校验)
E0702EL evaluation error(EL 表达式求值失败,如 ${wf:…} 写错)

通用排查路径(按成本从低到高):

  1. oozie job -info <id>:看作业/动作状态与 Err Code 列;
  2. oozie job -log <id>:看该作业的服务端日志(错误堆栈常在此);
  3. 服务端 logs/oozie.log 与 embedded-oozie-server 下的 jetty 输出:看启动/初始化类问题;
  4. mysql -uoozie -poozie123 -h127.0.0.1 -P3306 -e "SELECT id, status FROM oozie.WF_JOBS;":与 CLI 交叉核对持久化状态。

9.4 FAQ

Q1:提交后作业 ID 返回了,但 job -info 报作业不存在? A:先核对 OOZIE_URL 与提交时是否同一服务端;再确认 oozie.wf.application.path 指向的 HDFS 目录确实存在且含 workflow.xml(本文实测路径 hdfs://oozie:9000/user/root/examples/apps/map-reduce)。

Q2:动作长期 PREP 不动? A:九成是服务端启动/提交类异常:按 9.1 查 oozie job -log 的 Caused by,按 9.2 补 jar 重启后 kill 重提。Ext ID 长期 - 说明 launcher 作业根本没提交出去。

Q3:mr-node 报 Ext Status 失败,去哪看业务日志? A:Ext ID 即 YARN application ID,用 yarn logs -applicationId <ExtID> 或 YARN WebUI 查 launcher/业务日志;开启 yarn.log-aggregation-enable 后日志聚合到 HDFS。

Q4:coordinator 的 Nominal Time 怎么算? A:按 frequency(cron 或 frequency+timeunit)从 start 起在 timezone 时区内逐个落点(实测 0/10 * * * * + UTC 区间 18:40~18:50 只落 18:40 一个点,见 6.4);job -info 的 Nominal Time 列即该动作的触发时刻。

Q5:coordinator 触发的 workflow 从哪里看? A:oozie job -info <coord-id> 动作行的 Ext ID 就是 workflow 实例 ID(实测 C@1 → 0000002-…-W),对其再 job -info/job -log 即可。

Q6:改了 job.properties 里的参数要重传 workflow 吗? A:不用。workflow.xml/coordinator.xml 在 HDFS 上不变,业务参数来自提交侧 job.properties(4.2);只有改 workflow/coordinator 定义本身才需要重新上传 HDFS 对应目录。

十、参考链接