自动配置Oozie的脚本

wen 实用脚本 25
#!/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

功能特点

  1. 自动检测环境:检查Java、Hadoop版本和路径
  2. 目录管理:自动创建所需的目录结构
  3. 数据库配置
    • 支持 Derby、MySQL、PostgreSQL
    • 自动下载数据库驱动(如果存在)
    • 初始化数据库模式
  4. Hadoop集成
    • 自动配置代理用户
    • 复制Hadoop配置文件
    • 上传共享库到HDFS
  5. 配置生成:自动生成完整的oozie-site.xml
  6. 服务管理:自动启动并验证Oozie服务

生产环境建议

对于生产环境,建议:

自动配置Oozie的脚本

  1. 使用 MySQL 或 PostgreSQL 代替 Derby
  2. 启用授权服务(设置oozie.service.AuthorizationService.authorization.enabled=true
  3. 配置 HTTPS
  4. 设置合适的 JVM 参数
  5. 配置监控和告警

验证安装

# 检查服务状态
./oozie admin -oozie http://localhost:11000/oozie -status
# 提交测试工作流
./oozie job -oozie http://localhost:11000/oozie \
    -config /path/to/job.properties \
    -run

这个脚本提供了自动化的Oozie部署方案,可以大大简化配置过程,根据实际环境调整数据库配置即可快速部署。

抱歉,评论功能暂时关闭!