Files
doris/tools/single-node-cluster/multi-fe
zhangdong b129c9901b [improvement](FQDN)Change the implementation of fqdn (#19123)
Main changes:
1. If fqdn is enabled in the configuration file, when fe starts, localAddr will obtain fqdn instead of IP, priority_ Networks will fail
2. The IP and host names of Backend and Front are combined into one field, host. When fqdn is enabled, it represents the host name, and when not enabled, it represents the IP address
3. The communication between clusters directly uses fqdn, and various Connection pool add authentication mechanisms to prevent the IP address of the domain name from changing and the connection between nodes from making errors
4. No longer requires polling to verify if the IP has changed, delete fqdnManager
5. Change the method of verifying the legitimacy of nodes between FEs from obtaining client IP to displaying the identity of the transmitting node itself in the HTTP request header or the message body of the throttle
6. When processing the heartbeat, if BE finds that the host stored by itself is inconsistent with the host stored by the master, after verifying the legitimacy of the host, it will change its own host instead of directly reporting an error
7. Simplify the generation logic of fe name

Scope of influence:
1. Establishing communication connections between clusters
2. Determine whether it is the same node through attributes such as IP
3. Print Log
4. Information display
5. Address Splicing
6. k8s deployment
7. Upgrade compatibility

Test plan:
1. Change the IP address of the node, while keeping the fqdn unchanged, change the IP addresses of fe and be, and verify whether the cluster can read and write data normally
2. Use the master code to generate metadata, and use the previous metadata on the current pr to verify whether it is compatible with the old version (upgrading is no longer supported if fqdn has been enabled before)
3. Deploy fe and be clusters using k8s to verify whether the cluster can read and write data normally
4. According to https://doris.apache.org/zh-CN/docs/dev/admin-manual/cluster-management/fqdn?_highlight=fqdn#%E6%97%A7%E9%9B%86%E7%BE%A4%E5%90%AF%E7%94%A8fqdn Upgrading old clusters
5. Use streamload to specify the fqdn of fe and be to import data separately
6. Use different users to start transactions and write data using insert statements
2023-05-11 00:44:48 +08:00

271 lines
6.0 KiB
Bash

#!/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.
set -e
CURRENT_PATH="$(
cd "$(dirname "${BASH_SOURCE[0]}")"
pwd
)"
OUTPUT_PATH="$(readlink -f "${CURRENT_PATH}/../../output")"
readonly CURRENT_PATH
readonly OUTPUT_PATH
function log() {
local level="${1}"
local message="${2}"
local date
date="$(date +'%Y-%m-%d %H:%M:%S')"
if [[ "${level}" == 'INFO' ]]; then
level="[\033[32;1m ${level} \033[0m]"
elif [[ "${level}" == 'WARNING' ]]; then
level="[\033[33;1m${level}\033[0m]"
elif [[ "${level}" == 'ERROR' ]]; then
level="[\033[31;1m ${level} \033[0m]"
fi
echo -e "${level} ${date} - ${message}"
}
function log_info() {
local message="${1}"
log 'INFO' "${message}"
}
function log_warning() {
local message="${1}"
log 'WARNING' "${message}"
}
function log_error() {
local message="${1}"
log 'ERROR' "${message}"
exit 1
}
function help() {
cat >&2 <<EOF
${BASH_SOURCE[0]} start|stop|clean [OPTIONS ...]
start -n <NUM> -l <LIBRARY_PATH> -p <BASE_PORT>
Start the FE cluster.
-n The number of FEs.
-l The FE library path (default: doris/output/fe/lib)
-p The base port to generate all needed ports (default: 9030).
stop Stop the FE cluster.
clean Clean the data (rm -rf "\$(pwd)"/fe*).
EOF
exit 1
}
function parse_options() {
NUMBER_INSTANCES=1
PORT=9010
LIBS_PATH="${OUTPUT_PATH}/fe/lib"
ACTION="${1}"
if ! shift 1; then
help
fi
local option
while getopts "+n:p:l:" option; do
case "${option}" in
n)
NUMBER_INSTANCES="${OPTARG}"
;;
p)
PORT="${OPTARG}"
;;
l)
LIBS_PATH="$(readlink -f "${OPTARG}")"
;;
*)
help
;;
esac
done
readonly NUMBER_INSTANCES
readonly PORT
readonly LIBS_PATH
}
function prepare() {
local port="${1}"
local doris_home="${2}"
local log_dir="${3}"
local conf_dir="${doris_home}/conf"
local meta_dir="${doris_home}/doris-meta"
local http_port=8030
mkdir -p "${doris_home}"
mkdir -p "${log_dir}"
mkdir -p "${conf_dir}"
mkdir -p "${meta_dir}"
cat >"${conf_dir}/fe.conf" <<EOF
LOG_DIR = ${log_dir}
meta_dir = ${meta_dir}
edit_log_port = $((port + id))
rpc_port = $((port + 10 + id))
query_port = $((port + 20 + id))
http_port = $((http_port + id))
sys_log_level = INFO
sys_log_verbose_modules = org.apache.doris
mysql_service_nio_enabled = true
enable_ssl = false
priority_networks = 127.0.0.1/32
EOF
}
function mysql_command() {
local command="${1}"
local query_port
query_port="$(grep 'query_port' "${CURRENT_PATH}/fe1/conf/fe.conf" | sed 's/query_port[[:space:]]*=[[:space:]]*//')"
mysql -h127.0.0.1 -P"${query_port}" -uroot -e "${command}" -s -N
}
function create_role_and_version() {
local id="${1}"
local http_port
local header
local meta_dir
http_port="$(grep 'http_port' "${CURRENT_PATH}/fe1/conf/fe.conf" | sed 's/http_port[[:space:]]*=[[:space:]]*//')"
while true; do
mysql_command "ALTER SYSTEM ADD FOLLOWER \"127.0.0.1:$((PORT + id))\"" >/dev/null 2>&1 || true
if header="$(curl --noproxy '127.0.0.1' --silent --head --fail -H "CLIENT_NODE_HOST:127.0.0.1" -H "CLIENT_NODE_PORT:$((PORT + id))" "http://127.0.0.1:${http_port}/check")"; then
break
fi
log_info "Waiting for the Master FE to be ready ..."
sleep 1
done
meta_dir="$(grep 'meta_dir' "${CURRENT_PATH}/fe${id}/conf/fe.conf" | sed 's/meta_dir[[:space:]]*=[[:space:]]*//')"
mkdir -p "${meta_dir}/image"
echo "${header}" | sed -n '/cluster_id/,/token/p' | sed '{s/cluster_id: /clusterId=/;s/token: /token=/;}' \
>"${meta_dir}/image/VERSION"
cat >"${meta_dir}/image/ROLE" <<EOF
role=FOLLOWER
name=$(
set -e
mysql_command "SHOW FRONTENDS" | grep "127.0.0.1_$((PORT + id))" | awk '{print $1}'
)
EOF
}
function start_fe() {
local id="${1}"
local port="${2}"
local libs_path="${3}"
local doris_home
local helper
doris_home="$(pwd)/fe${id}"
local pid_dir="${doris_home}"
local log_dir="${doris_home}/log"
if [[ -f "${pid_dir}/fe.pid" ]]; then
if xargs kill -0 <"${pid_dir}/fe.pid"; then
log_warning "FE(${id}) is running..."
return
fi
fi
prepare "${port}" "${doris_home}" "${log_dir}"
declare -a classpath=("${libs_path}")
for lib in "${libs_path}"/*.jar; do
classpath+=("${lib}")
done
if [[ "${id}" -gt 1 ]]; then
helper="-helper 127.0.0.1:$((PORT + 1))"
create_role_and_version "${id}"
fi
pushd "${doris_home}" >/dev/null
DORIS_HOME="${doris_home}" \
PID_DIR="${doris_home}" \
nohup java -cp "$(
IFS=:
echo "${classpath[*]}"
)" org.apache.doris.DorisFE ${helper:+${helper}} >>"${log_dir}/fe.out" 2>&1 &
if kill -0 $!; then
log_info "Start FE(${id}) successfully"
else
log_warning "Failed to start FE(${id})"
fi
popd >/dev/null
}
function start() {
if [[ -z "${LIBS_PATH}" ]]; then
help
fi
log_info "NUMBER: ${NUMBER_INSTANCES}"
log_info "BASE PORT: ${PORT}"
log_info "LIBRARY_PATH: ${LIBS_PATH}"
for i in $(seq "${NUMBER_INSTANCES}"); do
start_fe "${i}" "${PORT}" "${LIBS_PATH}"
done
}
function stop() {
local pid
while read -r file; do
pid="$(<"${file}")"
if kill "${pid}"; then
log_info "Stopped FE (${pid}) successfully"
else
log_warning "Failed to stop FE (${pid})"
fi
done < <(find "$(pwd)"/fe* -name 'fe.pid')
}
function clean() {
rm -rf "$(pwd)"/fe*
log_info "Clean all data successfully"
}
function main() {
parse_options "${@}"
case "${ACTION}" in
start) start ;;
stop) stop ;;
clean) clean ;;
*)
help
;;
esac
}
main "${@}"