mirror of
https://github.com/apache/impala.git
synced 2025-12-19 18:12:08 -05:00
This patch provides LSB-compliant init scripts for impala package, administrator can manage impala services by the following commands: 'service <impala_service> <start|stop|restart|status|force-reload' This patch also change the owner of package files to 'impala', and launch process by the same user. Testing: - Manually deploy package on Ubuntu22.04 and verify it. Change-Id: If202e91e4b05adbc96cd5c556654901d2f7ca9fe Reviewed-on: http://gerrit.cloudera.org:8080/21994 Reviewed-by: Impala Public Jenkins <impala-public-jenkins@cloudera.com> Tested-by: Impala Public Jenkins <impala-public-jenkins@cloudera.com>
310 lines
11 KiB
Bash
Executable File
310 lines
11 KiB
Bash
Executable File
#!/bin/bash
|
|
#
|
|
# Licensed to the Apache Software Foundation (ASF) under one
|
|
# or more contributor license agreements. See the NOTICE file
|
|
# distributed with this work for additional information
|
|
# regarding copyright ownership. The ASF licenses this file
|
|
# to you under the Apache License, Version 2.0 (the
|
|
# "License"); you may not use this file except in compliance
|
|
# with the License. You may obtain a copy of the License at
|
|
#
|
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
#
|
|
# Unless required by applicable law or agreed to in writing,
|
|
# software distributed under the License is distributed on an
|
|
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
|
# KIND, either express or implied. See the License for the
|
|
# specific language governing permissions and limitations
|
|
# under the License.
|
|
#
|
|
# Script to manage Apache Impala services.
|
|
# User can customize environment variables in '../conf/impala-env.sh'.
|
|
# User can customize flags in '../conf/[impalad_flags...]', or override them in
|
|
# commandline arguments when needed(e.g. multiple instance).
|
|
#
|
|
# To launch impalad using another username (e.g. "impala"):
|
|
# sudo -E -u impala bin/impala.sh start impalad
|
|
#
|
|
# Note for setup:
|
|
# Please set the correct JAVA_HOME in '../conf/impala-env.sh'.
|
|
# Please set the correct hostnames in '../conf/[impalad_flags...]'.
|
|
# Please modify core-site.xml, hdfs-site.xml, hive-site.xml in conf based on the cluster.
|
|
set -euo pipefail
|
|
|
|
init() {
|
|
: ${IMPALA_HOME:=$(cd $(dirname ${0})/..;pwd)}
|
|
export IMPALA_HOME
|
|
. ${IMPALA_HOME}/conf/impala-env.sh
|
|
}
|
|
|
|
check_counts() {
|
|
local counts=${1} period=${2}
|
|
[[ ${counts} =~ ^[0-9]+$ ]] || (echo "Invalid waiting counts:${counts}." && exit 1)
|
|
[[ ${period} =~ ^[1-9][0-9]*$ ]] || (echo "Invalid waiting period:${period}." && exit 1)
|
|
}
|
|
|
|
# Return 0 if service is running, else otherwise.
|
|
status() {
|
|
local service=
|
|
while [[ $# -gt 0 ]]; do
|
|
case ${1} in
|
|
impalad|catalogd|admissiond|statestored) service=${1} && shift && break ;;
|
|
*) >&2 usage && exit 1 ;;
|
|
esac
|
|
done
|
|
[[ ${service} != "" ]] || (>&2 usage && exit 1)
|
|
local service_pidfile_key=${service^^}_PIDFILE
|
|
local service_pidfile=${!service_pidfile_key}
|
|
if [[ ! -f ${service_pidfile} ]]; then
|
|
>&2 echo "${service} is stopped."
|
|
return 1
|
|
fi
|
|
local pid=$(cat ${service_pidfile})
|
|
if ps -p ${pid} -o comm=|grep ${service} &> /dev/null ; then
|
|
echo "${service} is running with PID ${pid}."
|
|
return 0
|
|
fi
|
|
>&2 echo "${service} is stopped."
|
|
return 1
|
|
}
|
|
|
|
# Return 0 if service is stopped in expected time, else otherwise.
|
|
stop_await() {
|
|
local service=${1} service_pidfile=${2} counts=${3} period=${4}
|
|
[[ "${counts}" == "0" ]] && return 0
|
|
for ((i=1; ${counts} == -1 || i<=${counts}; i++)); do
|
|
[[ ${i} -gt 1 ]] && sleep ${period}
|
|
if ! kill -0 ${pid} &> /dev/null; then
|
|
rm -f ${service_pidfile} &&\
|
|
echo "(${i}/${counts}) ${service} is stopped." &&\
|
|
return 0
|
|
else
|
|
echo "(${i}/${counts}) Waiting ${service} to stop."
|
|
fi
|
|
done
|
|
return 1
|
|
}
|
|
|
|
stop() {
|
|
local service= counts=20 period=2 signal=SIGTERM force=false grace=false
|
|
while [[ $# -gt 0 ]]; do
|
|
case ${1} in
|
|
-c) counts=${2} && shift 2 ;;
|
|
-p) period=${2} && shift 2 ;;
|
|
-f) signal=SIGKILL && force=true && shift 1 ;;
|
|
-g) signal=SIGRTMIN && grace=true && shift 1 ;;
|
|
impalad|catalogd|admissiond|statestored) service=${1} && shift && break ;;
|
|
*) >&2 usage && exit 1 ;;
|
|
esac
|
|
done
|
|
check_counts ${counts} ${period}
|
|
[[ ${service} != "" ]] || (>&2 usage && exit 1)
|
|
# Disable graceful shutdown timeout.
|
|
[[ ${grace} == true ]] && counts=-1 || true
|
|
if [[ ${grace} == true && ${force} == true ]]; then
|
|
echo "Cannot use '-g' and '-f' together."
|
|
exit 1
|
|
fi
|
|
if [[ ${grace} == true && ${service} != impalad ]]; then
|
|
echo "Warning: Cannot apply '-g' to ${service} service."
|
|
signal=SIGTERM
|
|
fi
|
|
local service_pidfile_key=${service^^}_PIDFILE
|
|
local service_pidfile=${!service_pidfile_key}
|
|
if [[ ! -f ${service_pidfile} ]]; then
|
|
echo "Already stopped: PID file '${service_pidfile}' not found."
|
|
return 0
|
|
fi
|
|
local pid=$(cat ${service_pidfile})
|
|
if ! ps -p ${pid} -o comm=|grep ${service} &> /dev/null ; then
|
|
rm -f ${service_pidfile}
|
|
echo "Already stopped: ${service} is not running with PID ${pid}." \
|
|
"Removed stale file '${service_pidfile}'."
|
|
return 0
|
|
fi
|
|
echo "Killing ${service} with PID ${pid}."
|
|
kill -${signal} ${pid}
|
|
if ! stop_await ${service} ${service_pidfile} ${counts} ${period}; then
|
|
if [[ ${grace} == true ]]; then
|
|
kill -SIGKILL ${pid}
|
|
echo "Timed out waiting ${service} to graceful shutdown."
|
|
return 0
|
|
else
|
|
echo "Timed out waiting ${service} to stop, check logs for more details."
|
|
return 1
|
|
fi
|
|
fi
|
|
}
|
|
|
|
prerun() {
|
|
local message=${1:-"on"}
|
|
: ${JAVA_HOME:?"JAVA_HOME must be set to the location of your JDK!"}
|
|
if [[ ${message} == "on" ]]; then
|
|
echo "Using JAVA_HOME: ${JAVA_HOME}"
|
|
fi
|
|
local lib_jvm_dir=$(dirname $(find ${JAVA_HOME} -type f -name libjvm.so | head -1))
|
|
local lib_jsig_dir=$(dirname $(find ${JAVA_HOME} -type f -name libjsig.so | head -1))
|
|
if [[ -n "${HADOOP_HOME:=}" ]]; then
|
|
: ${HADOOP_LIB_DIR:=${HADOOP_HOME}/lib/native}
|
|
if [[ ${message} == "on" ]]; then
|
|
echo "Using hadoop native libs in '${HADOOP_LIB_DIR}'"
|
|
fi
|
|
else
|
|
: ${HADOOP_LIB_DIR:=${IMPALA_HOME}/lib/native}
|
|
if [[ ${message} == "on" ]]; then
|
|
echo "HADOOP_HOME not set, using hadoop native libs in '${HADOOP_LIB_DIR}'"
|
|
fi
|
|
fi
|
|
export LIBHDFS_OPTS="${LIBHDFS_OPTS:=} -Djava.library.path=${HADOOP_LIB_DIR}"
|
|
export LC_ALL=en_US.utf8
|
|
export CLASSPATH="${CLASSPATH}:${IMPALA_HOME}/conf:${IMPALA_HOME}/lib/jars/*"
|
|
export LD_LIBRARY_PATH+=":${IMPALA_HOME}/lib/native:${lib_jvm_dir}:${lib_jsig_dir}"
|
|
}
|
|
|
|
start() {
|
|
prerun
|
|
local service= counts=20 period=2
|
|
while [[ $# -gt 0 ]]; do
|
|
case ${1} in
|
|
-c) counts=${2} && shift 2 ;;
|
|
-p) period=${2} && shift 2 ;;
|
|
# Ignore the '-f' and '-g' parameter to support the restart command.
|
|
-f|-g) shift 1 ;;
|
|
impalad|catalogd|admissiond|statestored) service=${1} && shift && break ;;
|
|
*) >&2 usage && exit 1 ;;
|
|
esac
|
|
done
|
|
check_counts ${counts} ${period}
|
|
[[ ${service} != "" ]] || (>&2 usage && exit 1)
|
|
status ${service} 2> /dev/null && return 0
|
|
local service_flagfile=${IMPALA_HOME}/conf/${service}_flags
|
|
local service_stdout_key=${service^^}_OUTFILE
|
|
local service_stderr_key=${service^^}_ERRFILE
|
|
local service_pidfile_key=${service^^}_PIDFILE
|
|
local service_stdout=${!service_stdout_key}
|
|
local service_stderr=${!service_stderr_key}
|
|
local service_pidfile=${!service_pidfile_key}
|
|
mkdir -p $(dirname ${service_pidfile})
|
|
echo "Service stdout is redirected to '${service_stdout}'."
|
|
echo "Service stderr is redirected to '${service_stderr}'."
|
|
# User can override '--flagfile' in the following commandline arguments.
|
|
${IMPALA_HOME}/sbin/${service} \
|
|
--flagfile=${service_flagfile} \
|
|
${@} >> ${service_stdout} 2>> ${service_stderr} &
|
|
local pid=$!
|
|
echo ${pid} > ${service_pidfile}
|
|
# Sleep 1s so the glog output won't be messed up with waiting messages.
|
|
sleep 1
|
|
health -c ${counts} -p ${period} ${service}
|
|
}
|
|
|
|
restart() {
|
|
stop ${@} && start ${@}
|
|
}
|
|
|
|
health() {
|
|
local service= counts=20 period=2 code=
|
|
while [[ $# -gt 0 ]]; do
|
|
case ${1} in
|
|
-c) counts=${2} && shift 2 ;;
|
|
-p) period=${2} && shift 2 ;;
|
|
impalad|catalogd|admissiond|statestored) service=${1} && shift ;;
|
|
*) >&2 usage && exit 1 ;;
|
|
esac
|
|
done
|
|
check_counts ${counts} ${period}
|
|
[[ "${counts}" == "0" ]] && exit 0
|
|
[[ ${service} != "" ]] || (>&2 usage && exit 1)
|
|
status ${service} > /dev/null || exit 1
|
|
# Determine Web Server port
|
|
local service_flagfile=${IMPALA_HOME}/conf/${service}_flags
|
|
local service_pidfile_key=${service^^}_PIDFILE
|
|
local service_pidfile=${!service_pidfile_key}
|
|
local pid=$(cat ${service_pidfile})
|
|
local port=
|
|
if [[ $(ps --cols 10000 -o args= -p ${pid}) =~ -webserver_port=([0-9]+) ]]; then
|
|
port=${BASH_REMATCH[1]}
|
|
else
|
|
port=$(awk -F= '/-webserver_port=/ {print $2;}' ${service_flagfile})
|
|
fi
|
|
if [[ -z "${port}" ]]; then
|
|
case ${service} in
|
|
impalad) port=25000;;
|
|
catalogd) port=25020;;
|
|
admissiond) port=25030;;
|
|
statestored) port=25010;;
|
|
esac
|
|
fi
|
|
# Request healthz code
|
|
for ((i=1; i<=${counts}; i++)); do
|
|
[[ ${i} -gt 1 ]] && sleep ${period} || true
|
|
if ! code=$(curl -s http://localhost:${port}/healthz); then
|
|
status ${service} > /dev/null || exit 1
|
|
echo "(${i}/${counts}) ${service} on port ${port} is not ready."
|
|
elif [[ "${code}" != "OK" ]]; then
|
|
echo "(${i}/${counts}) Waiting for ${service} to be ready."
|
|
else
|
|
echo "(${i}/${counts}) ${service} is ready."
|
|
exit 0
|
|
fi
|
|
done
|
|
echo "Timed out waiting for ${service} to be ready, check logs for more details."
|
|
exit 1
|
|
}
|
|
|
|
usage() {
|
|
echo "Usage: $0 <command> [<options>] <service> [<flags>]"
|
|
echo " $0 --version"
|
|
echo " $0 --help"
|
|
echo " command: {start|stop|restart|status|health}"
|
|
echo " service: {impalad|catalogd|admissiond|statestored}"
|
|
echo " flags: in pattern '-key=val...'."
|
|
echo
|
|
echo " start: start an Impala daemon service, wait until service is ready."
|
|
echo " options:"
|
|
echo " -c: maximum count of checks, defaults to 20."
|
|
echo " -p: seconds of period between checks, defaults to 2."
|
|
echo
|
|
echo " stop: stop an Impala daemon service, wait until service is stopped."
|
|
echo " options:"
|
|
echo " -c: maximum count of checks, defaults to 20."
|
|
echo " -f: force kill a daemon service."
|
|
echo " -g: graceful shutdown the impalad service."
|
|
echo " -p: seconds of period between checks, defaults to 2."
|
|
echo
|
|
echo " restart: restart an Impala daemon service."
|
|
echo " options:"
|
|
echo " -c: maximum count of checks, defaults to 20."
|
|
echo " -f: force kill a daemon service."
|
|
echo " -g: graceful shutdown the impalad service."
|
|
echo " -p: seconds of period between checks, defaults to 2."
|
|
echo
|
|
echo " status: check the process status of an Impala daemon service."
|
|
echo
|
|
echo " health: waiting until an Impala daemon service is ready."
|
|
echo " options:"
|
|
echo " -c: maximum count of checks, defaults to 20."
|
|
echo " -p: seconds of period between checks, defaults to 2."
|
|
}
|
|
|
|
version() {
|
|
if init &> /dev/null && prerun off && ${IMPALA_HOME}/sbin/impalad --version ; then
|
|
exit 0
|
|
fi
|
|
echo "Failed to get version!"
|
|
exit 1
|
|
}
|
|
|
|
main() {
|
|
[[ $# -ge 1 && ${1} == "--help" ]] && usage && exit 0
|
|
[[ $# -ge 1 && ${1} == "--version" ]] && version && exit 0
|
|
[[ $# -lt 2 ]] && >&2 usage && exit 1
|
|
local command=${1}
|
|
case ${command} in
|
|
start|stop|restart|status|health) shift && init && ${command} ${@} ;;
|
|
*) >&2 usage && exit 1 ;;
|
|
esac
|
|
}
|
|
|
|
main ${@}
|