本文档风哥主要介绍Oozie工作流调度实战,包括架构原理、安装配置、工作流开发等内容,风哥教程参考Oozie官方文档Workflow、Coordinator等内容,适合大数据开发运维人员在学习和测试中使用,如果要应用于生产环境则需要自行确认。更多视频教程www.fgedu.net.cn
Part01-基础概念与理论知识
1.1 Oozie概述
Oozie是一个基于Hadoop的工作流调度系统,用于管理Hadoop作业的执行。学习交流加群风哥微信: itpux-com
- 工作流调度:支持DAG工作流
- 定时调度:支持定时和依赖调度
- 多种作业:支持MapReduce、Spark、Hive等
- 可扩展:支持自定义作业类型
Oozie是Apache开源项目,专门用于Hadoop生态系统的
工作流调度系统。
主要功能:
1. 工作流管理
– 定义作业执行顺序
– 管理作业依赖关系
– 控制作业执行流程
2. 定时调度
– 支持Cron表达式
– 支持数据依赖
– 支持时间触发
3. 作业管理
– 提交作业
– 监控作业
– 重试失败作业
# Oozie组件
1. Workflow
– 定义作业流程
– 控制节点和动作节点
– 支持分支和并行
2. Coordinator
– 定时调度工作流
– 数据依赖触发
– 支持周期性执行
3. Bundle
– 批量管理Coordinator
– 统一启动停止
– 批量操作
# Oozie支持的作业类型
作业类型 说明
map-reduce MapReduce作业
spark Spark作业
hive Hive作业
pig Pig作业
sqoop Sqoop作业
shell Shell脚本
java Java程序
fs HDFS操作
sub-workflow 子工作流
# Oozie优势
1. 与Hadoop深度集成
2. 支持复杂工作流
3. 高可用性
4. 可扩展性强
5. 可视化界面
# Oozie应用场景
1. ETL数据管道
数据采集 -> 数据清洗 -> 数据加载 -> 数据分析
2. 定时报表
定时执行数据统计 -> 生成报表 -> 发送邮件
3. 数据同步
定时同步数据 -> 数据验证 -> 数据备份
4. 机器学习管道
数据准备 -> 特征工程 -> 模型训练 -> 模型评估
1.2 架构设计
Oozie架构设计详解:
┌─────────────────────────────────────────┐
│ Oozie Web UI │
└───────────────────┬─────────────────────┘
│
┌───────────────────┴─────────────────────┐
│ Oozie Server │
│ ┌─────────────────────────────────┐ │
│ │ Workflow Engine │ │
│ └─────────────────────────────────┘ │
│ ┌─────────────────────────────────┐ │
│ │ Coordinator Engine │ │
│ └─────────────────────────────────┘ │
│ ┌─────────────────────────────────┐ │
│ │ Bundle Engine │ │
│ └─────────────────────────────────┘ │
└───────────────────┬─────────────────────┘
│
┌───────────────────┴─────────────────────┐
│ Hadoop Cluster │
│ ┌─────────┐ ┌─────────┐ ┌─────────┐ │
│ │ HDFS │ │ YARN │ │ Hive │ │
│ └─────────┘ └─────────┘ └─────────┘ │
└─────────────────────────────────────────┘
# Oozie Server
1. Workflow Engine
– 解析工作流定义
– 执行工作流节点
– 管理工作流状态
2. Coordinator Engine
– 解析调度定义
– 触发工作流执行
– 管理调度状态
3. Bundle Engine
– 管理Coordinator组
– 批量操作
# 数据存储
1. HDFS
– 存储工作流定义文件
– 存储作业配置文件
– 存储作业输出
2. 数据库
– 存储工作流状态
– 存储作业历史
– 存储调度信息
# Oozie工作原理
1. 工作流提交
用户 -> Oozie CLI -> Oozie Server -> 创建作业
2. 作业执行
Oozie Server -> Hadoop -> 执行作业 -> 回调通知
3. 状态更新
Hadoop -> Oozie Server -> 更新状态 -> 数据库
# 高可用设计
1. Oozie Server高可用
– 多实例部署
– 负载均衡
– 故障转移
2. 数据库高可用
– 主从复制
– 自动故障转移
# 工作流生命周期
1. PREP:准备状态
2. RUNNING:运行状态
3. SUSPENDED:暂停状态
4. SUCCEEDED:成功状态
5. KILLED:终止状态
6. FAILED:失败状态
1.3 工作流模型详解
工作流模型详解:
1. 控制节点
– start:开始节点
– end:结束节点
– fork:分支节点
– join:合并节点
– decision:判断节点
– kill:终止节点
2. 动作节点
– map-reduce:MapReduce作业
– spark:Spark作业
– hive:Hive作业
– pig:Pig作业
– sqoop:Sqoop作业
– shell:Shell脚本
– java:Java程序
– fs:HDFS操作
– sub-workflow:子工作流
# 工作流定义示例
# 分支并行示例
…
…
…
# 判断节点示例
# Coordinator定义
# Bundle定义
Part02-生产环境规划与建议
2.1 环境规划建议
环境规划建议:
Oozie版本 Hadoop版本 Spark版本
5.3.x 3.3.x 3.5.x
5.2.x 3.2.x 3.4.x
推荐版本:Oozie 5.3.0 + Hadoop 3.3.6 + Spark 3.5.0
# 硬件规划
组件 配置 数量
Oozie Server 8C/16G/100G 2(高可用)
数据库 4C/8G/200G 2(主从)
# 软件依赖
1. Hadoop
– HDFS
– YARN
– MapReduce
2. 数据库
– MySQL 5.7+
– PostgreSQL 9.6+
– MariaDB 10.2+
3. 其他
– Java 8+
– Tomcat 8.5+
# 网络规划
端口 用途
11000 Oozie HTTP
11443 Oozie HTTPS
11001 Oozie Admin
# 目录规划
目录 用途
/bigdata/app/oozie 安装目录
/bigdata/app/oozie/logs 日志目录
/bigdata/app/oozie/data 数据目录
/user/fgedu/workflows 工作流目录
/user/fgedu/coordinators 调度目录
/user/fgedu/bundles Bundle目录
# 数据库规划
数据库 大小
oozie_db 50GB
表空间规划:
– 工作流表
– 作业历史表
– 调度表
– 配置表
# 高可用规划
1. Oozie Server
– 部署2个实例
– 负载均衡
– 故障转移
2. 数据库
– 主从复制
– 自动故障转移
2.2 工作流规划建议
工作流规划建议:
1. ETL工作流
用途:数据抽取、转换、加载
频率:每日/每小时
依赖:数据源可用
2. 报表工作流
用途:生成报表
频率:每日/每周
依赖:数据准备完成
3. 数据同步工作流
用途:数据同步
频率:每小时
依赖:源数据更新
4. 机器学习工作流
用途:模型训练
频率:每日
依赖:数据准备完成
# 工作流命名规范
格式:[业务]_[类型]_[频率]_[版本]
示例:
user_etl_daily_v1
order_report_weekly_v1
data_sync_hourly_v1
ml_training_daily_v1
# 工作流目录结构
/user/fgedu/
├── workflows/
│ ├── etl/
│ │ ├── user_etl/
│ │ │ ├── workflow.xml
│ │ │ ├── job.properties
│ │ │ └── lib/
│ │ └── order_etl/
│ ├── report/
│ └── sync/
├── coordinators/
│ ├── daily/
│ └── hourly/
└── bundles/
# 工作流参数规划
参数类型 示例
系统参数 ${jobTracker}, ${nameNode}
时间参数 ${coord:days(1)}
业务参数 ${database}, ${table}
自定义参数 ${inputPath}, ${outputPath}
# 工作流依赖规划
1. 数据依赖
– 输入数据可用
– 数据质量检查
2. 时间依赖
– 定时触发
– 时间窗口
3. 作业依赖
– 前置作业完成
– 资源可用
2.3 调度规划建议
调度规划建议:
1. 时间触发
– Cron表达式
– 固定周期
– 时间窗口
2. 数据触发
– 数据可用触发
– 数据集依赖
– 文件存在触发
3. 混合触发
– 时间+数据
– 多条件组合
# 调度频率规划
频率 表达式 适用场景
分钟 ${coord:minutes(5)} 实时监控
小时 ${coord:hours(1)} 实时统计
天 ${coord:days(1)} 日报表
周 ${coord:weeks(1)} 周报表
月 ${coord:months(1)} 月报表
# 调度时间窗口
业务 开始时间 结束时间
ETL 01:00 05:00
报表 06:00 08:00
同步 00:00 23:59
# 重试策略
参数 默认值 说明
retry-max 3 最大重试次数
retry-interval 10 重试间隔(分钟)
retry-policy exponential 重试策略
# 超时设置
参数 默认值 说明
timeout 30 作业超时(分钟)
concurrency 1 并发数
throttle 12 最大并发
# 告警配置
告警类型 触发条件
作业失败 作业执行失败
作业超时 作业执行超时
调度延迟 调度触发延迟
# 监控指标
指标 告警阈值
作业成功率 < 95%
作业延迟 > 30分钟
队列积压 > 100个
Part03-生产环境项目实施方案
3.1 安装配置实战
3.1.1 安装Oozie
$ cd /bigdata/app
$ wget https://archive.apache.org/dist/oozie/5.3.0/oozie-5.3.0.tar.gz
$ tar -xzf oozie-5.3.0.tar.gz
$ ln -s oozie-5.3.0 oozie
# 2. 配置环境变量
$ cat >> /etc/profile << 'EOF'
export OOZIE_HOME=/bigdata/app/oozie
export PATH=$PATH:$OOZIE_HOME/bin
EOF
$ source /etc/profile
# 3. 配置oozie-site.xml
$ cat > /bigdata/app/oozie/conf/oozie-site.xml << 'EOF'
EOF
# 4. 创建数据库
$ mysql -u root -p
mysql> CREATE DATABASE oozie_db DEFAULT CHARACTER SET utf8mb4;
mysql> CREATE USER ‘oozie’@’%’ IDENTIFIED BY ‘oozie123’;
mysql> GRANT ALL PRIVILEGES ON oozie_db.* TO ‘oozie’@’%’;
mysql> FLUSH PRIVILEGES;
# 5. 下载MySQL驱动
$ cp /bigdata/app/hive/lib/mysql-connector-java-8.0.30.jar /bigdata/app/oozie/lib/
# 6. 生成share lib
$ /bigdata/app/oozie/bin/oozie-setup.sh sharelib create -fs hdfs://fgedu-node1:8020 -locallib /bigdata/app/oozie/oozie-sharelib-5.3.0.tar.gz
setting OOZIE_HOME /bigdata/app/oozie
setting OOZIE_CONFIG /bigdata/app/oozie/conf
…
Share library created at: hdfs://fgedu-node1:8020/user/oozie/share/lib
# 7. 初始化数据库
$ /bigdata/app/oozie/bin/ooziedb.sh create -run
setting OOZIE_HOME /bigdata/app/oozie
setting OOZIE_CONFIG /bigdata/app/oozie/conf
…
Table ‘OOZIE_SYS’ already exists, skipping create
…
Oozie DB has been created for Oozie version ‘5.3.0’
# 8. 启动Oozie
$ /bigdata/app/oozie/bin/oozie-start.sh
setting OOZIE_HOME /bigdata/app/oozie
setting OOZIE_CONFIG /bigdata/app/oozie/conf
…
Oozie started
# 9. 验证安装
$ oozie admin -oozie http://localhost:11000/oozie -status
System mode: NORMAL
# 10. 访问Web UI
http://fgedu-node1:11000/oozie
3.1.2 配置高可用
$ cat >> /bigdata/app/oozie/conf/oozie-site.xml << 'EOF'
org.apache.oozie.service.SchedulerService,
org.apache.oozie.service.InstrumentationService,
org.apache.oozie.service.MemoryLocksService,
org.apache.oozie.service.UUIDService,
org.apache.oozie.service.ELService,
org.apache.oozie.service.AuthorizationService,
org.apache.oozie.service.UserGroupInformationService,
org.apache.oozie.service.HadoopAccessorService,
org.apache.oozie.service.JobsConcurrencyService,
org.apache.oozie.service.URIHandlerService,
org.apache.oozie.service.DagXLogInfoService,
org.apache.oozie.service.SchemaService,
org.apache.oozie.service.LiteWorkflowAppService,
org.apache.oozie.service.JPAService,
org.apache.oozie.service.StoreService,
org.apache.oozie.service.CoordinatorStoreService,
org.apache.oozie.service.SLAStoreService,
org.apache.oozie.service.DBLiteWorkflowStoreService,
org.apache.oozie.service.CallbackService,
org.apache.oozie.service.ActionService,
org.apache.oozie.service.ActionCheckerService,
org.apache.oozie.service.RecoveryService,
org.apache.oozie.service.PurgeService,
org.apache.oozie.service.CoordinatorEngineService,
org.apache.oozie.service.BundleEngineService,
org.apache.oozie.service.DagEngineService,
org.apache.oozie.service.CoordMaterializeTriggerService,
org.apache.oozie.service.StatusTransitService,
org.apache.oozie.service.PauseTransitService,
org.apache.oozie.service.GroupsService,
org.apache.oozie.service.ProxyUserService,
org.apache.oozie.service.XLogStreamingService,
org.apache.oozie.service.JvmPauseMonitorService
# 2. 配置负载均衡
$ cat > /etc/nginx/conf.d/oozie.conf << 'EOF'
upstream oozie_cluster {
server fgedu-node1:11000;
server fgedu-node2:11000;
}
server {
listen 11000;
server_name oozie.fgedu.net.cn;
location / {
proxy_pass http://oozie_cluster;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
EOF
$ systemctl restart nginx
# 3. 启动所有节点
# 在fgedu-node1
$ /bigdata/app/oozie/bin/oozie-start.sh
# 在fgedu-node2
$ /bigdata/app/oozie/bin/oozie-start.sh
# 4. 验证高可用
$ oozie admin -oozie http://oozie.fgedu.net.cn:11000/oozie -status
System mode: NORMAL
3.2 工作流开发实战
3.2.1 创建Hive工作流
$ hdfs dfs -mkdir -p /user/fgedu/workflows/hive_etl
# 2. 创建workflow.xml
$ cat > /tmp/workflow.xml << 'EOF'
EOF
$ hdfs dfs -put /tmp/workflow.xml /user/fgedu/workflows/hive_etl/
# 3. 创建Hive脚本
$ cat > /tmp/etl_script.hql << 'EOF'
-- etl_script.hql
-- from:www.itpux.com.qq113257174.wx:itpux-com
-- web: http://www.fgedu.net.cn
-- 创建临时表
CREATE EXTERNAL TABLE IF NOT EXISTS temp_user_data (
user_id STRING,
name STRING,
age INT,
city STRING
)
ROW FORMAT DELIMITED
FIELDS TERMINATED BY ','
LOCATION '${inputPath}';
-- 数据清洗和转换
INSERT OVERWRITE DIRECTORY '${outputPath}'
SELECT
user_id,
UPPER(name) as name,
age,
city,
CURRENT_TIMESTAMP as etl_time
FROM temp_user_data
WHERE age > 0 AND age < 150;
EOF
$ hdfs dfs -put /tmp/etl_script.hql /user/fgedu/workflows/hive_etl/
# 4. 创建job.properties
$ cat > /tmp/job.properties << 'EOF'
nameNode=hdfs://fgedu-node1:8020
jobTracker=fgedu-node1:8032
queueName=default
oozie.use.system.libpath=true
inputPath=/user/fgedu/input/user_data
outputPath=/user/fgedu/output/hive_etl
oozie.wf.application.path=${nameNode}/user/fgedu/workflows/hive_etl
EOF
# 5. 提交工作流
$ oozie job -config /tmp/job.properties -run
job: 0000000-260408000000001-oozie-W
# 6. 查看作业状态
$ oozie job -info 0000000-260408000000001-oozie-W
Job ID : 0000000-260408000000001-oozie-W
Workflow Name : fgedu-hive-etl
App Path : hdfs://fgedu-node1:8020/user/fgedu/workflows/hive_etl
Status : RUNNING
...
3.2.2 创建Spark工作流
$ hdfs dfs -mkdir -p /user/fgedu/workflows/spark_etl
# 2. 创建workflow.xml
$ cat > /tmp/spark_workflow.xml << 'EOF'
–executor-memory 4G
–executor-cores 2
–driver-memory 2G
–num-executors 10
EOF
$ hdfs dfs -put /tmp/spark_workflow.xml /user/fgedu/workflows/spark_etl/workflow.xml
# 3. 创建job.properties
$ cat > /tmp/spark_job.properties << 'EOF'
nameNode=hdfs://fgedu-node1:8020
jobTracker=fgedu-node1:8032
queueName=default
oozie.use.system.libpath=true
inputPath=/user/fgedu/input/user_data
outputPath=/user/fgedu/output/spark_etl
oozie.wf.application.path=${nameNode}/user/fgedu/workflows/spark_etl
EOF
# 4. 提交工作流
$ oozie job -config /tmp/spark_job.properties -run
job: 0000001-260408000000001-oozie-W
3.3 调度配置实战
$ hdfs dfs -mkdir -p /user/fgedu/coordinators/daily_etl
# 2. 创建coordinator.xml
$ cat > /tmp/coordinator.xml << 'EOF'
EOF
$ hdfs dfs -put /tmp/coordinator.xml /user/fgedu/coordinators/daily_etl/
# 3. 创建coordinator.properties
$ cat > /tmp/coordinator.properties << 'EOF'
nameNode=hdfs://fgedu-node1:8020
jobTracker=fgedu-node1:8032
queueName=default
oozie.use.system.libpath=true
oozie.coord.application.path=${nameNode}/user/fgedu/coordinators/daily_etl
EOF
# 4. 提交Coordinator
$ oozie job -config /tmp/coordinator.properties -run
job: 0000000-260408000000001-oozie-C
# 5. 查看Coordinator状态
$ oozie job -info 0000000-260408000000001-oozie-C
Job ID : 0000000-260408000000001-oozie-C
Coordinator Name : fgedu-daily-etl-coord
Status : RUNNING
...
# 6. 创建Bundle
$ hdfs dfs -mkdir -p /user/fgedu/bundles/etl_bundle
$ cat > /tmp/bundle.xml << 'EOF'
EOF
$ hdfs dfs -put /tmp/bundle.xml /user/fgedu/bundles/etl_bundle/
# 7. 提交Bundle
$ cat > /tmp/bundle.properties << 'EOF'
nameNode=hdfs://fgedu-node1:8020
jobTracker=fgedu-node1:8032
queueName=default
kickOffTime=2026-04-01T00:00Z
oozie.bundle.application.path=${nameNode}/user/fgedu/bundles/etl_bundle
EOF
$ oozie job -config /tmp/bundle.properties -run
job: 0000000-260408000000001-oozie-B
Part04-生产案例与实战讲解
4.1 ETL调度案例
# 1. ETL工作流设计
数据采集 -> 数据清洗 -> 数据转换 -> 数据加载 -> 数据验证
# 2. 创建完整ETL工作流
$ cat > /tmp/etl_workflow.xml << 'EOF'
EOF
# 3. 创建调度脚本
$ cat > /tmp/run_etl.sh << 'EOF'
#!/bin/bash
# run_etl.sh
# from:www.itpux.com.qq113257174.wx:itpux-com
# web: http://www.fgedu.net.cn
DATE=$1
if [ -z "$DATE" ]; then
DATE=$(date -d "yesterday" +%Y-%m-%d)
fi
echo "运行ETL: $DATE"
# 更新job.properties
cat > /tmp/etl_job.properties << PROPS
nameNode=hdfs://fgedu-node1:8020
jobTracker=fgedu-node1:8032
queueName=default
oozie.use.system.libpath=true
date=$DATE
oozie.wf.application.path=\${nameNode}/user/fgedu/workflows/etl
PROPS
# 提交作业
JOB_ID=$(oozie job -config /tmp/etl_job.properties -run)
echo "作业ID: $JOB_ID"
# 等待作业完成
while true; do
STATUS=$(oozie job -info $JOB_ID | grep "Status" | awk '{print $3}')
echo "作业状态: $STATUS"
if [ "$STATUS" == "SUCCEEDED" ]; then
echo "ETL完成"
exit 0
elif [ "$STATUS" == "FAILED" ] || [ "$STATUS" == "KILLED" ]; then
echo "ETL失败"
exit 1
fi
sleep 60
done
EOF
$ chmod +x /tmp/run_etl.sh
$ /tmp/run_etl.sh 2026-04-08
运行ETL: 2026-04-08
作业ID: job: 0000002-260408000000001-oozie-W
作业状态: RUNNING
作业状态: RUNNING
作业状态: SUCCEEDED
ETL完成
4.2 数据管道案例
# 1. 创建数据管道工作流
$ cat > /tmp/pipeline_workflow.xml << 'EOF'
ETL Pipeline completed successfully.
本文由风哥教程整理发布,仅用于学习测试使用,转载注明出处:http://www.fgedu.net.cn/10327.html
