Bootstrap

hive 自动检测、自动重启、记录检测日志、自动清理日志

最终效果

  • 定时检测hive运行状态,进程不存在或者进程存在但是不监听端口的hiveserver2,自动重新拉起
  • 每次检测脚本执行的日志都会保存在log目录下.check文件,每一个月一个文件
  • 每月15日,删除2月前的检测日志
  • 开启hive自带日志输出后,日志不会删除,且较大,因此一并将过期的hive自带日志清空

https://blog.csdn.net/Brother_ning/article/details/127993943
从这个作者复制的,但是他的代码好像有点问题,修改后然后加以优化

定时检查脚本

vi $HIVE_HOME/hiveservice.sh

#!/bin/bash

HIVE_LOG_DIR=$HIVE_HOME/log
CURRENT_TIME=$(date +"%Y-%m-%d %H:%M:%S")
# 日志清理,如果与hive默认日志命名风格一样,也会自动清理hive的日志
DT=$(date)
DT_2M=$(date -d "2 month ago")
CHECK_LOG=$HIVE_LOG_DIR/hive.log.$(date "+%Y-%m").check
CHECK_LOG_REG=$HIVE_LOG_DIR/hive.log.$(date -d "2 month ago" +"%Y-%m")-*
METASTORE_PORT=9083
HIVESERVER2_PORT=10000
# 最大连接数,超过这个数,则重启hive
MAX_WORKS=1800
if [ ! -d $HIVE_LOG_DIR ]
then
    mkdir -p $HIVE_LOG_DIR
fi

check_process(){
    WORKS=$(netstat -anltp|grep $HIVESERVER2_PORT|wc -l)
    if [ "$WORKS" -gt $MAX_WORKS ]; then
        echo "$CURRENT_TIME:链接数异常,重启hive" | tee -a $CHECK_LOG
        hive_stop
        sleep 5
    fi
    pid=$(ps -ef 2>/dev/null | grep -v grep | grep -i $1 | awk '{print $2}')
    ppid=$(netstat -nltp 2>/dev/null | grep $2 | awk '{print $7}' | cut -d '/' -f 1)
    if [ -n "$pid" ] && [ -n "$ppid" ] && [ "$pid" = "$ppid" ]; then
        echo $pid
        return 0 # 进程正在运行
    else
        return 1 # 进程未运行
    fi
}


hive_stop()
{
    metapid=$(check_process HiveMetastore $METASTORE_PORT)
    if [ -n "$metapid" ]; then
        echo "$CURRENT_TIME:关闭Metastore进程" | tee -a $CHECK_LOG & kill -9 $metapid
    fi
    server2pid=$(check_process HiveServer2 $HIVESERVER2_PORT)
    if [ -n "$server2pid" ]; then
        echo "$CURRENT_TIME:关闭server2进程" | tee -a $CHECK_LOG & kill -9 $server2pid
    fi
}

# wait方法不能随意使用,必须在启动执行后才能执行。
wait_start()
{
    local max_retries=100  # 设置最大重试次数 100次,重启时间200秒,如果200秒内没有启动成功,则认为启动失败。
    local retries=0       # 初始化重试计数器

    metapid=$(check_process HiveMetastore $METASTORE_PORT)
    server2pid=$(check_process HiveServer2 $HIVESERVER2_PORT)

    while { [ -z "$metapid" ] || [ -z "$server2pid" ]; } && [ $retries -lt $max_retries ]; do
        sleep 2
        echo "$(date +"%Y-%m-%d %H:%M:%S"):启动中($retries)。。。" | tee -a $CHECK_LOG
        metapid=$(check_process HiveMetastore $METASTORE_PORT)
        server2pid=$(check_process HiveServer2 $HIVESERVER2_PORT)
        retries=$((retries + 1))
    done

    # 检查是否达到最大重试次数
    if [ $retries -ge $max_retries ]; then
        echo "$CURRENT_TIME:达到最大重试次数,启动失败" | tee -a $CHECK_LOG
        exit 1  # 退出脚本,表示启动失败
    else
        echo "$CURRENT_TIME:HIVE状态正常" | tee -a $CHECK_LOG
    fi
}

kill_valid()
{
    PIDS=$(jps -m | grep $1 | awk '{print$1}')
    # 遍历所有PID并使用kill -9命令杀掉它们,防止hive挂掉,但是进程不退出
    for PID in $PIDS; do
        kill -9 $PID
        echo "$CURRENT_TIME:kill无效的$1进程 $PID" | tee -a $CHECK_LOG
        sleep 3
    done
}

hive_start()
{
    metapid=$(check_process HiveMetastore $METASTORE_PORT)
    if [ -z "$metapid" ]; then
        kill_valid HiveMetaStore
        echo "$CURRENT_TIME:Metastore启动中" | tee -a $CHECK_LOG
        nohup hive --service metastore 2>$HIVE_LOG_DIR/metastore.log 1>/dev/null &
    fi
    server2pid=$(check_process HiveServer2 $HIVESERVER2_PORT)
    if [ -z "$server2pid" ]; then
        kill_valid HiveServer2
        echo "$CURRENT_TIME:HiveServer2启动中" | tee -a $CHECK_LOG
        nohup hive --service hiveserver2 2>$HIVE_LOG_DIR/hiveServer2.log 1>/dev/null &
    fi
}

status()
{
    metapid=$(check_process HiveMetastore $METASTORE_PORT)
    server2pid=$(check_process HiveServer2 $HIVESERVER2_PORT)

    if [ -n "$metapid" ] && [ -n "$server2pid" ]; then
        echo "$CURRENT_TIME:HIVE状态正常" | tee -a $CHECK_LOG
    else
        if [ -z "$metapid" ]; then
            echo "$CURRENT_TIME:Metastore未运行" | tee -a $CHECK_LOG
        fi
        if [ -z "$server2pid" ]; then
            echo "$CURRENT_TIME:HiveServer2未运行" | tee -a $CHECK_LOG
        fi
    fi
}

clean()
{
    echo "$CURRENT_TIME:清空日志 rm -rf $CHECK_LOG_REG" | tee -a $CHECK_LOG
    rm -rf $CHECK_LOG_REG
}


case $1 in
"start")
    hive_start
    wait_start
    ;;
"stop")
    hive_stop
    status
    ;;
"restart")
    hive_stop
    sleep 3
    hive_start
    wait_start
    ;;
"status")
    status
    ;;
"clean")
    clean
    ;;
*)
    echo Invalid Args!
    echo 'Usage: '$(basename $0)' start|stop|restart|status|clean'
    ;;
esac

定时调度

crontab -e
输入如下内容,注意修改环境变量,cron无法正常读取系统环境变量

#设置 HIVE_HOME 环境变量
HIVE_HOME=/data/soft/hive-3.1.2
# 每隔10分钟执行一次状态检测,有问题自动重启
*/10 * * * * sh $HIVE_HOME/hiveservice.sh start
# 每周天在0点01分执行一次 restart 任务
1 0 * * 0 sh $HIVE_HOME/hiveservice.sh restart >> $HIVE_HOME/log/cron.restart.log
# 每月15号清空2月前的hive日志
0 0 15 * * sh $HIVE_HOME/hiveservice.sh clean

crontab -l
检查crontab运行任务
tail -f /var/log/cron (centos)
cat /var/log/syslog (乌班图)

;