#!/bin/bash
# Oozie Auto-Configuration Script
# 适用于 CDH/HDP 或原生 Apache Hadoop 环境
set -e
# ========== 配置参数 ==========
HADOOP_HOME=${HADOOP_HOME:-/usr/local/hadoop}
OOZIE_HOME=${OOZIE_HOME:-/usr/local/oozie}
OOZIE_USER=${OOZIE_USER:-oozie}
OOZIE_HTTP_PORT=${OOZIE_HTTP_PORT:-11000}
OOZIE_ADMIN_PORT=${OOZIE_ADMIN_PORT:-11001}
# 数据库配置 (默认使用嵌入式 Derby,生产环境建议用 MySQL/PostgreSQL)
DB_TYPE=${DB_TYPE:-derby}
DB_HOST=${DB_HOST:-localhost}
DB_PORT=${DB_PORT:-1527}
DB_NAME=${DB_NAME:-oozie}
DB_USER=${DB_USER:-oozie}
DB_PASSWORD=${DB_PASSWORD:-oozie}
# Hadoop 配置文件路径
CORE_SITE=${HADOOP_HOME}/etc/hadoop/core-site.xml
HDFS_SITE=${HADOOP_HOME}/etc/hadoop/hdfs-site.xml
YARN_SITE=${HADOOP_HOME}/etc/hadoop/yarn-site.xml
MAPRED_SITE=${HADOOP_HOME}/etc/hadoop/mapred-site.xml
# ========== 颜色输出 ==========
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m'
info() { echo -e "${GREEN}[INFO]${NC} $1"; }
warn() { echo -e "${YELLOW}[WARN]${NC} $1"; }
error() { echo -e "${RED}[ERROR]${NC} $1"; exit 1; }
# ========== 前置检查 ==========
pre_check() {
info "执行前置检查..."
# 检查 Java
if ! command -v java &> /dev/null; then
error "Java 未安装,请先安装 JDK 1.8+"
fi
JAVA_VERSION=$(java -version 2>&1 | head -n 1 | cut -d'"' -f2 | cut -d'.' -f1)
if [ "$JAVA_VERSION" -lt 8 ]; then
error "需要 JDK 1.8 或更高版本,当前版本: $(java -version 2>&1 | head -n 1)"
fi
# 检查 Hadoop
if [ ! -f "$CORE_SITE" ]; then
error "Hadoop 配置文件未找到: $CORE_SITE"
fi
# 检查 Oozie 安装
if [ ! -f "${OOZIE_HOME}/bin/oozie" ]; then
error "Oozie 未找到在: ${OOZIE_HOME}"
fi
# 检查用户
if [ "$(whoami)" != "$OOZIE_USER" ] && [ "$(whoami)" != "root" ]; then
error "请使用 $OOZIE_USER 用户或 root 运行此脚本"
fi
}
# ========== 创建必要目录 ==========
create_dirs() {
info "创建 Oozie 数据目录..."
local dirs=(
"${OOZIE_HOME}/data"
"${OOZIE_HOME}/logs"
"${OOZIE_HOME}/libext"
"${OOZIE_HOME}/oozie-server/webapps/oozie/WEB-INF/lib"
)
for dir in "${dirs[@]}"; do
mkdir -p "$dir"
done
# 设置权限
chown -R $OOZIE_USER:$OOZIE_USER "${OOZIE_HOME}/data" "${OOZIE_HOME}/logs"
}
# ========== 配置数据库 ==========
configure_database() {
info "配置数据库 ($DB_TYPE)..."
# 复制数据库驱动
case $DB_TYPE in
derby)
# Derby 驱动通常在 Oozie 安装包中
if [ -f "${OOZIE_HOME}/oozie-server/lib/derby.jar" ]; then
cp "${OOZIE_HOME}/oozie-server/lib/derby.jar" "${OOZIE_HOME}/libext/"
fi
;;
mysql)
if [ -f "/usr/share/java/mysql-connector-java.jar" ]; then
cp "/usr/share/java/mysql-connector-java.jar" "${OOZIE_HOME}/libext/"
elif [ -f "/usr/share/java/mysql-connector-java-8.0.28.jar" ]; then
cp "/usr/share/java/mysql-connector-java-8.0.28.jar" "${OOZIE_HOME}/libext/"
else
warn "MySQL 驱动未找到,请手动下载到 ${OOZIE_HOME}/libext/"
fi
;;
postgresql)
if [ -f "/usr/share/java/postgresql-jdbc.jar" ]; then
cp "/usr/share/java/postgresql-jdbc.jar" "${OOZIE_HOME}/libext/"
else
warn "PostgreSQL 驱动未找到,请手动下载到 ${OOZIE_HOME}/libext/"
fi
;;
*)
warn "未知的数据库类型: $DB_TYPE,使用 Derby"
DB_TYPE="derby"
;;
esac
}
# ========== 生成 Oozie 配置文件 ==========
generate_oozie_config() {
info "生成 Oozie 配置文件..."
local config_file="${OOZIE_HOME}/conf/oozie-site.xml"
# 备份原配置
if [ -f "$config_file" ]; then
cp "$config_file" "${config_file}.bak.$(date +%Y%m%d%H%M%S)"
fi
# 生成新配置
cat > "$config_file" <<EOF
<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
<configuration>
<!-- 基础配置 -->
<property>
<name>oozie.base.url</name>
<value>http://$(hostname -f):${OOZIE_HTTP_PORT}/oozie</value>
</property>
<property>
<name>oozie.http.port</name>
<value>${OOZIE_HTTP_PORT}</value>
</property>
<property>
<name>oozie.admin.port</name>
<value>${OOZIE_ADMIN_PORT}</value>
</property>
<!-- 数据库配置 -->
<property>
<name>oozie.service.JPAService.jdbc.driver</name>
<value>$(get_jdbc_driver)</value>
</property>
<property>
<name>oozie.service.JPAService.jdbc.url</name>
<value>$(get_jdbc_url)</value>
</property>
<property>
<name>oozie.service.JPAService.jdbc.username</name>
<value>${DB_USER}</value>
</property>
<property>
<name>oozie.service.JPAService.jdbc.password</name>
<value>${DB_PASSWORD}</value>
</property>
<!-- 服务配置 -->
<property>
<name>oozie.service.AuthorizationService.authorization.enabled</name>
<value>false</value>
<description>生产环境建议启用</description>
</property>
<property>
<name>oozie.service.HadoopAccessorService.hadoop.configurations</name>
<value>*=${HADOOP_HOME}/etc/hadoop</value>
</property>
<!-- 系统配置 -->
<property>
<name>oozie.system.id</name>
<value>oozie-$(hostname -s)</value>
</property>
<property>
<name>oozie.systemmode</name>
<value>NORMAL</value>
</property>
<!-- 本地路径配置 -->
<property>
<name>oozie.local.dir</name>
<value>${OOZIE_HOME}/data</value>
</property>
<property>
<name>oozie.log.dir</name>
<value>${OOZIE_HOME}/logs</value>
</property>
</configuration>
EOF
chown $OOZIE_USER:$OOZIE_USER "$config_file"
info "配置文件已生成: $config_file"
}
get_jdbc_driver() {
case $DB_TYPE in
derby) echo "org.apache.derby.jdbc.EmbeddedDriver" ;;
mysql) echo "com.mysql.cj.jdbc.Driver" ;;
postgresql) echo "org.postgresql.Driver" ;;
esac
}
get_jdbc_url() {
case $DB_TYPE in
derby)
echo "jdbc:derby:${OOZIE_HOME}/data/oozie-db;create=true"
;;
mysql)
echo "jdbc:mysql://${DB_HOST}:${DB_PORT}/${DB_NAME}?useSSL=false"
;;
postgresql)
echo "jdbc:postgresql://${DB_HOST}:${DB_PORT}/${DB_NAME}"
;;
esac
}
# ========== 配置 Hadoop 集成 ==========
configure_hadoop_integration() {
info "配置 Hadoop 集成..."
# 添加 Oozie 代理用户配置(如果不存在)
local core_site_content=$(cat "$CORE_SITE")
if ! echo "$core_site_content" | grep -q "hadoop.proxyuser.${OOZIE_USER}.hosts"; then
# 使用临时文件修改 XML
python3 -c "
import xml.etree.ElementTree as ET
tree = ET.parse('$CORE_SITE')
root = tree.getroot()
# 添加代理用户配置
properties = [
('hadoop.proxyuser.${OOZIE_USER}.hosts', '*'),
('hadoop.proxyuser.${OOZIE_USER}.groups', '*')
]
for name, value in properties:
prop = ET.SubElement(root, 'property')
name_elem = ET.SubElement(prop, 'name')
name_elem.text = name
value_elem = ET.SubElement(prop, 'value')
value_elem.text = value
tree.write('$CORE_SITE', xml_declaration=True)
"
info "已添加 Oozie 代理用户配置到 core-site.xml"
fi
# 复制 Hadoop 配置到 Oozie
cp "$CORE_SITE" "$OOZIE_HOME/conf/core-site.xml"
cp "$HDFS_SITE" "$OOZIE_HOME/conf/hdfs-site.xml"
cp "$YARN_SITE" "$OOZIE_HOME/conf/yarn-site.xml"
cp "$MAPRED_SITE" "$OOZIE_HOME/conf/mapred-site.xml" 2>/dev/null || true
# 添加 Hadoop 库
if [ -d "${HADOOP_HOME}/share/hadoop" ]; then
find "${HADOOP_HOME}/share/hadoop" -name "*.jar" -type f | \
xargs -I {} cp {} "${OOZIE_HOME}/libext/" 2>/dev/null || true
info "已复制 Hadoop 库到 Oozie libext"
fi
}
# ========== 初始化数据库 ==========
initialize_database() {
info "初始化 Oozie 数据库..."
cd "$OOZIE_HOME"
# 检查数据库是否已初始化
if [ "$DB_TYPE" = "derby" ] && [ -d "${OOZIE_HOME}/data/oozie-db" ]; then
warn "Derby 数据库已存在,跳过初始化"
return
fi
# 执行数据库初始化
bin/ooziedb.sh create -sqlfile oozie.sql -run
if [ $? -eq 0 ]; then
info "数据库初始化成功"
else
error "数据库初始化失败,请检查日志"
fi
cd - > /dev/null
}
# ========== 准备 Oozie 共享库 ==========
prepare_sharelib() {
info "准备 Oozie 共享库..."
cd "$OOZIE_HOME"
# 检查是否已准备
if hdfs dfs -test -d /user/oozie/share/lib 2>/dev/null; then
warn "共享库已存在 HDFS 中,跳过上传"
return
fi
# 创建共享库目录
mkdir -p libext
bin/oozie-setup.sh sharelib create -fs hdfs://$(hdfs getconf -namenodes 2>/dev/null || echo "localhost:9000")
if [ $? -eq 0 ]; then
info "共享库已上传到 HDFS"
else
warn "共享库上传失败,请手动执行: bin/oozie-setup.sh sharelib create -fs <namenode>"
fi
cd - > /dev/null
}
# ========== 启动 Oozie 服务 ==========
start_oozie() {
info "启动 Oozie 服务..."
# 检查是否已在运行
if pgrep -f "org.apache.oozie.server.OozieServer" > /dev/null; then
warn "Oozie 服务已在运行"
return
fi
cd "$OOZIE_HOME"
# 使用 oozie 用户启动
if [ "$(whoami)" = "root" ]; then
su - $OOZIE_USER -c "${OOZIE_HOME}/bin/oozied.sh start"
else
bin/oozied.sh start
fi
# 等待服务启动
sleep 5
# 检查服务状态
if bin/oozie admin -oozie http://localhost:${OOZIE_HTTP_PORT}/oozie -status 2>/dev/null; then
info "Oozie 服务启动成功"
info "访问地址: http://$(hostname -f):${OOZIE_HTTP_PORT}/oozie"
else
warn "Oozie 状态检查失败,请查看日志: ${OOZIE_HOME}/logs/oozie.log"
fi
cd - > /dev/null
}
# ========== 主函数 ==========
main() {
echo "========================================"
echo " Oozie 自动配置脚本 v1.0"
echo "========================================"
echo
# 解析命令行参数
while [[ $# -gt 0 ]]; do
case $1 in
--hadoop-home) HADOOP_HOME="$2"; shift 2 ;;
--oozie-home) OOZIE_HOME="$2"; shift 2 ;;
--db-type) DB_TYPE="$2"; shift 2 ;;
--db-host) DB_HOST="$2"; shift 2 ;;
--db-port) DB_PORT="$2"; shift 2 ;;
--db-name) DB_NAME="$2"; shift 2 ;;
--db-user) DB_USER="$2"; shift 2 ;;
--db-password) DB_PASSWORD="$2"; shift 2 ;;
--http-port) OOZIE_HTTP_PORT="$2"; shift 2 ;;
--admin-port) OOZIE_ADMIN_PORT="$2"; shift 2 ;;
--help|-h)
echo "用法: $0 [选项]"
echo "选项:"
echo " --hadoop-home <path> Hadoop 安装目录"
echo " --oozie-home <path> Oozie 安装目录"
echo " --db-type <type> 数据库类型 (derby|mysql|postgresql)"
echo " --db-host <host> 数据库主机"
echo " --db-port <port> 数据库端口"
echo " --db-name <name> 数据库名称"
echo " --db-user <user> 数据库用户名"
echo " --db-password <pass> 数据库密码"
echo " --http-port <port> HTTP 端口"
echo " --admin-port <port> 管理端口"
exit 0
;;
*) error "未知参数: $1" ;;
esac
done
# 执行步骤
pre_check
create_dirs
configure_database
generate_oozie_config
configure_hadoop_integration
initialize_database
prepare_sharelib
start_oozie
echo
echo "========================================"
echo " Oozie 配置完成!"
echo " 管理界面: http://$(hostname -f):${OOZIE_HTTP_PORT}/oozie"
echo "========================================"
}
# 执行主函数
main "$@"
使用方法
基本用法
# 下载脚本并赋予执行权限
chmod +x oozie-auto-config.sh
# 使用默认配置运行
./oozie-auto-config.sh
# 指定自定义路径
./oozie-auto-config.sh \
--hadoop-home /opt/hadoop \
--oozie-home /opt/oozie \
--db-type mysql \
--db-host localhost \
--db-port 3306 \
--db-name oozie \
--db-user oozie \
--db-password oozie123
参数说明
| 参数 | 说明 | 默认值 |
|---|---|---|
--hadoop-home |
Hadoop安装目录 | /usr/local/hadoop |
--oozie-home |
Oozie安装目录 | /usr/local/oozie |
--db-type |
数据库类型(derby/mysql/postgresql) | derby |
--db-host |
数据库主机地址 | localhost |
--db-port |
数据库端口 | 1527(derby) |
--db-name |
数据库名称 | oozie |
--db-user |
数据库用户名 | oozie |
--db-password |
数据库密码 | oozie |
--http-port |
Oozie HTTP端口 | 11000 |
--admin-port |
Oozie管理端口 | 11001 |
功能特点
- 自动检测环境:检查Java、Hadoop版本和路径
- 目录管理:自动创建所需的目录结构
- 数据库配置:
- 支持 Derby、MySQL、PostgreSQL
- 自动下载数据库驱动(如果存在)
- 初始化数据库模式
- Hadoop集成:
- 自动配置代理用户
- 复制Hadoop配置文件
- 上传共享库到HDFS
- 配置生成:自动生成完整的
oozie-site.xml - 服务管理:自动启动并验证Oozie服务
生产环境建议
对于生产环境,建议:

- 使用 MySQL 或 PostgreSQL 代替 Derby
- 启用授权服务(设置
oozie.service.AuthorizationService.authorization.enabled=true) - 配置 HTTPS
- 设置合适的 JVM 参数
- 配置监控和告警
验证安装
# 检查服务状态
./oozie admin -oozie http://localhost:11000/oozie -status
# 提交测试工作流
./oozie job -oozie http://localhost:11000/oozie \
-config /path/to/job.properties \
-run
这个脚本提供了自动化的Oozie部署方案,可以大大简化配置过程,根据实际环境调整数据库配置即可快速部署。