在現代數據處理和工作流管理中,Apache DolphinScheduler以其靈活性和強大的調度能力受到開發者的廣泛歡迎。
本文將逐步解析DolphinScheduler的關鍵腳本,希望能提供一個詳盡的操作指南,幫助大家掌握安裝、配置和操作的每一步。
建立在./bin/env/下目錄的配置文件建立好的前提。
安裝流程解析
./install.sh
- 通過source獲取install_env.sh和dolphinscheduler_env.sh中的環境變量,如master、worker的基本信息。
- 在當前機器上創建安裝目錄,並給目錄授權。
- 向其他節點發送dolphinscheduler的解壓文件
- 停止所有的服務
- 刪除zk上的dolphinscheduler根節點
- 啓動dolphinscheduler所有的服務。
拷貝文件到工作節點
workDir=`dirname $0`
workDir=`cd ${workDir};pwd`
source ${workDir}/env/install_env.sh
# 獲取workers=${workers:-"ds1:default,ds2:default,ds3:default,ds4:default,ds5:default"}
# 獲取數組
workersGroup=(${workers//,/ })
# 順序取數組中的值
for workerGroup in ${workersGroup[@]}
do
# 比如:ds1:default
echo $workerGroup;
# 獲取worker的ip
worker=`echo $workerGroup|awk -F':' '{print $1}'`
# 獲取worker對應ip的組,默認爲default
group=`echo $workerGroup|awk -F':' '{print $2}'`
# 將ip放置到一個集合
workerNames+=($worker)
# 組放到一個集合
groupNames+=(${group:-default})
done
# 獲取需要安裝的機器ip: ips=${ips:-"ds1,ds2,ds3,ds4,ds5"}
hostsArr=(${ips//,/ })
# 開始遍歷所有需要安裝的機器
for host in ${hostsArr[@]}
do
# 連接目標ip,驗證安裝目錄是否存在,如果不存在,則會進行文件夾的創建,因此,需要事先創建好ssh免密登錄
if ! ssh -o StrictHostKeyChecking=no -p $sshPort $host test -e $installPath; then
# 創建安裝目錄 比如:/home/dolphinscheduler/apache-dolphinscheduler
ssh -o StrictHostKeyChecking=no -p $sshPort $host "sudo mkdir -p $installPath; sudo chown -R $deployUser:$deployUser $installPath"
fi
如果當前機器時server-worker的機器
echo "scp dirs to $host/$installPath starting"
for i in ${!workerNames[@]}; do
if [[ ${workerNames[$i]} == $host ]]; then
workerIndex=$i
break
fi
done
# 這裏表示用給定的組去替換default這個字符串,不過配置文件中,默認是不存在這個值的,暫時不用管
# set worker groups in application.yaml
[[ -n ${workerIndex} ]] && sed -i "s/- default/- ${groupNames[$workerIndex]}/" $workDir/../worker-server/conf/application.yaml
# 將相關的七個文件都拷貝到安裝目錄下。
for dsDir in bin master-server worker-server alert-server api-server ui tools
do
echo "start to scp $dsDir to $host/$installPath"
# Use quiet mode to reduce command line output
scp -q -P $sshPort -r $workDir/../$dsDir $host:$installPath
done
# restore worker groups to default
[[ -n ${workerIndex} ]] && sed -i "s/- ${groupNames[$workerIndex]}/- default/" $workDir/../worker-server/conf/application.yaml
echo "scp dirs to $host/$installPath complete"
done
Zookeeper上根節點的刪除
執行命令:
bash ${workDir}/remove-zk-node.sh $zkRoot
具體的腳本細節:
print_usage(){
printf $"USAGE:$0 rootNode\n"
exit 1
}
# 如果啓動參數的個數不等於1,就會報錯,
if [ $# -ne 1 ];then
print_usage
fi
# 獲取zk上的rootNode: /dolphinscheduler
rootNode=$1
# 獲取當前 remove-zk-node.sh 腳本的目錄,bin
BIN_DIR=`dirname $0`
BIN_DIR=`cd "$BIN_DIR"; pwd`
# 獲取dolphin的根目錄,可能是安裝目錄,可能是包目錄
DOLPHINSCHEDULER_HOME=$BIN_DIR/..
# 刷新環境變量
source ${BIN_DIR}/env/install_env.sh
source ${BIN_DIR}/env/dolphinscheduler_env.sh
# 獲取java環境
export JAVA_HOME=$JAVA_HOME
# 設置配置文件目錄,不過不存在配置文件目錄
export DOLPHINSCHEDULER_CONF_DIR=$DOLPHINSCHEDULER_HOME/conf
# 獲取需要的lib包
export DOLPHINSCHEDULER_LIB_JARS=$DOLPHINSCHEDULER_HOME/api-server/libs/*
# 下面就是具體的執行命令:
export DOLPHINSCHEDULER_OPTS="-Xmx1g -Xms1g -Xss512k -XX:+DisableExplicitGC -XX:+UseConcMarkSweepGC -XX:+CMSParallelRemarkEnabled -XX:LargePageSizeInBytes=128m -XX:+UseCMSInitiatingOccupancyOnly -XX:CMSInitiatingOccupancyFraction=70 "
export STOP_TIMEOUT=5
CLASS=org.apache.zookeeper.ZooKeeperMain
exec_command="$DOLPHINSCHEDULER_OPTS -classpath $DOLPHINSCHEDULER_CONF_DIR:$DOLPHINSCHEDULER_LIB_JARS $CLASS -server $REGISTRY_ZOOKEEPER_CONNECT_STRING rmr $rootNode"
cd $DOLPHINSCHEDULER_HOME
$JAVA_HOME/bin/java $exec_command
# 下面來看下這個具體的執行命令是什麼?
/bin/java -Xmx1g -Xms1g -Xss512k
-XX:+DisableExplicitGC -XX:+UseConcMarkSweepGC
-XX:+CMSParallelRemarkEnabled -XX:LargePageSizeInBytes=128m
-XX:+UseCMSInitiatingOccupancyOnly -XX:CMSInitiatingOccupancyFraction=70
# 類路徑下的參數
-classpath /conf:/api-server/libs/*
# 啓動的主要類
org.apache.zookeeper.ZooKeeperMain
# 啓動的相關參數,這個是zookeeper自身定義的東西,參數需要查看zookeepeer的類
# 主要是zookeeper的連接信息,主要從 dophinscheduler_env.sh 腳本中獲取的變量:export REGISTRY_ZOOKEEPER_CONNECT_STRING=${REGISTRY_ZOOKEEPER_CONNECT_STRING:-localhost:2181}
-server localhost:2181 rmr /dolphinscheduler
整體啓停流程解析
# 一鍵開啓集羣所有服務
bash ./bin/start-all.sh
# 一鍵關閉集羣所有服務
bash ./bin/stop-all.sh
啓動過程如下:
- 通過source獲取install_env.sh中的變量,及api-server、master-server、worker-server、alert-server這幾個dolphin中節點的基本部署信息。
- 通過ssh在各個節點上使用 dolphinscheduler-daemon.sh 命令對各個服務做啓停。
- 啓停順序爲 master-server、worker-server、alert-server、api-server。
- 啓動時最後會通過 status-all.sh 對各個服務的狀態做查詢。
節點狀態查詢解析
根據作者本人所瞭解的,獲取服務的狀態一般通過兩種方式:
- 啓動服務時,將服務的進程id寫入到文件中,通常在/var/run/目錄中,當然,也可以自定義目錄。
- 通過ps命令獲取對應的進程id。
當然,Apache DolphinScheduler也是通過寫進程文件pid
的方式來獲取進程id
來查詢服務狀態和停止服務的。
如何單節點啓停以及狀態查詢
在海豚調度的整個啓動,停止,狀態查詢中,最終所用到的腳本是 dolphinscheduler-daemon.sh
。
有時候,因爲某種原因,可能導致Apache DolphinScheduler集羣中某一個服務掛掉,不可能通過start-all.sh
命令來操作所有,同時,在集羣各個服務的擴縮容中,也需要單節點啓動,因此合理使用該腳本就比較重要。
命令的使用規範:
dolphinscheduler-daemon.sh (start|stop|status) <api-server|master-server|worker-server|alert-server|standalone-server>
腳本解析
dolphinscheduler-daemon.sh
腳本
# 這是一個用法的示例
usage="Usage: dolphinscheduler-daemon.sh (start|stop|status) <api-server|master-server|worker-server|alert-server|standalone-server> "
# 攜帶的參數必須是兩個,如果是一個就會報錯
# if no args specified, show usage
if [ $# -le 1 ]; then
echo $usage
exit 1
fi
# 執行的命令
startStop=$1
# shift相當於是將$2 變成$1,
shift
# 執行的任務類型
command=$1
shift
echo "Begin $startStop $command......"
BIN_DIR=`dirname $0`
BIN_DIR=`cd "$BIN_DIR"; pwd`
# 獲取安裝路徑的家目錄,注意,因爲執行的時候,cd 到了installPath
DOLPHINSCHEDULER_HOME=`cd "$BIN_DIR/.."; pwd`
# 獲取dolphin的環境變量,爲下面的環境變量覆蓋做幫助
BIN_ENV_FILE="${DOLPHINSCHEDULER_HOME}/bin/env/dolphinscheduler_env.sh"
# 這段話的意思就是使用/bin/env/dolphinscheduler_env.sh配置文件,代替每個服務下配置目錄conf下的配置文件
# Overwrite server dolphinscheduler_env.sh in path `<server>/conf/dolphinscheduler_env.sh` when exists
# `bin/env/dolphinscheduler_env.sh` file. User could only change `bin/env/dolphinscheduler_env.sh` instead
# of each server's dolphinscheduler_env.sh when they want to start the server
# 定義了一個函數,具體看後面的使用,覆蓋環境變量
function overwrite_server_env() {
local server=$1
local server_env_file="${DOLPHINSCHEDULER_HOME}/${server}/conf/dolphinscheduler_env.sh"
if [ -f "${BIN_ENV_FILE}" ]; then
echo "Overwrite ${server}/conf/dolphinscheduler_env.sh using bin/env/dolphinscheduler_env.sh."
cp "${BIN_ENV_FILE}" "${server_env_file}"
else
echo "Start server ${server} using env config path ${server_env_file}, because file ${BIN_ENV_FILE} not exists."
fi
}
# 當前機器的hostname
export HOSTNAME=`hostname`
# 執行命令服務的日誌文件
export DOLPHINSCHEDULER_LOG_DIR=$DOLPHINSCHEDULER_HOME/$command/logs
# 設置超時時間
export STOP_TIMEOUT=5
# 創建日誌文件夾
if [ ! -d "$DOLPHINSCHEDULER_LOG_DIR" ]; then
mkdir $DOLPHINSCHEDULER_LOG_DIR
fi
# 定義服務的啓動進程文件
pid=$DOLPHINSCHEDULER_HOME/$command/pid
# 進入到服務的主目錄
cd $DOLPHINSCHEDULER_HOME/$command
# 服務的運行日誌,out日誌
if [ "$command" = "api-server" ]; then
log=$DOLPHINSCHEDULER_HOME/api-server/logs/$command-$HOSTNAME.out
elif [ "$command" = "master-server" ]; then
log=$DOLPHINSCHEDULER_HOME/master-server/logs/$command-$HOSTNAME.out
elif [ "$command" = "worker-server" ]; then
log=$DOLPHINSCHEDULER_HOME/worker-server/logs/$command-$HOSTNAME.out
elif [ "$command" = "alert-server" ]; then
log=$DOLPHINSCHEDULER_HOME/alert-server/logs/$command-$HOSTNAME.out
elif [ "$command" = "standalone-server" ]; then
log=$DOLPHINSCHEDULER_HOME/standalone-server/logs/$command-$HOSTNAME.out
else
echo "Error: No command named '$command' was found."
exit 1
fi
# 定義一個函數,獲取服務的當前狀態
state=""
function get_server_running_status() {
state="STOP"
if [ -f $pid ]; then
TARGET_PID=`cat $pid`
if [[ $(ps -p "$TARGET_PID" -o comm=) =~ "bash" ]]; then
state="RUNNING"
fi
fi
}
# 使用case語句,根據情況做啓動,停止,狀態查看
case $startStop in
(start)
# if server is already started, cancel this launch
# 如果服務已經啓動,直接退出啓動過程
get_server_running_status
if [[ $state == "RUNNING" ]]; then
echo "$command running as process $TARGET_PID. Stop it first."
exit 1
fi
# 開始做啓動
echo starting $command, logging to $DOLPHINSCHEDULER_LOG_DIR
# 覆蓋配置文件
overwrite_server_env "${command}"
# 執行具體的命令,輸入到日誌文件,並將標準輸出2重定向到標準輸出1
nohup /bin/bash "$DOLPHINSCHEDULER_HOME/$command/bin/start.sh" > $log 2>&1 &
echo $! > $pid
;;
# 停止服務,通過kill命令
(stop)
if [ -f $pid ]; then
TARGET_PID=`cat $pid`
if kill -0 $TARGET_PID > /dev/null 2>&1; then
echo stopping $command
pkill -P $TARGET_PID
sleep $STOP_TIMEOUT
if kill -0 $TARGET_PID > /dev/null 2>&1; then
echo "$command did not stop gracefully after $STOP_TIMEOUT seconds: killing with kill -9"
pkill -P -9 $TARGET_PID
fi
else
echo no $command to stop
fi
rm -f $pid
else
echo no $command to stop
fi
;;
# 查詢狀態
(status)
get_server_running_status
if [[ $state == "STOP" ]]; then
# font color - red
state="[ \033[1;31m $state \033[0m ]"
else
# font color - green
state="[ \033[1;32m $state \033[0m ]"
fi
echo -e "$command $state"
;;
(*)
echo $usage
exit 1
;;
啓動腳本關鍵點說明
這裏主要講一點關於env中配置目錄中的關鍵點,可以發現在dolphinscheduler_env.sh中有一些數據庫方面的配置。如下:
# Database related configuration, set database type, username and password
export DATABASE=${DATABASE:-postgresql}
export SPRING_PROFILES_ACTIVE=${DATABASE}
export SPRING_DATASOURCE_URL
export SPRING_DATASOURCE_USERNAME
export SPRING_DATASOURCE_PASSWORD
比較瞭解SpringBoot的同學知道,JAVA的配置一般是來自於Yaml文件中的,因此對於一些初試用的同學對配置可能就比較迷惑。
打開spring的官網: https://docs.spring.io/spring-boot/docs/2.2.9.RELEASE/reference/htmlsingle/#boot-features-external-config, 我們可以看到有這樣的描述:
SpringBoot使用一種非常特殊的PropertySource順序,旨在允許合理地覆蓋值。按以下順序考慮屬性:
- $HOME/.config/spring-boot當 devtools 處於活動狀態時,文件夾中的Devtools全局設置屬性。
- @TestPropertySource對你的測試進行註釋。
- properties測試的屬性。可用於測試應用程序的特定部分的測試@SpringBootTest註釋。
- 命令行參數。
- 來自SPRING_APPLICATION_JSON(嵌入環境變量或系統屬性中的內聯 JSON)的屬性。
- ServletConfig初始化參數。
- ServletContext初始化參數。
- JNDI 屬性來自java:comp/env.
- Java 系統屬性 ( System.getProperties())。
- 操作系統環境變量。
- ARandomValuePropertySource僅在 中具有屬性random.*。
- 打包的 jar(和 YAML 變體)之外的特定於配置文件的應用程序屬性application-{profile}.properties。
- 特定於配置文件的應用程序屬性打包在 jar(application-{profile}.properties和 YAML 變體)內。
- 打包的 jar(和 YAML 變體)之外的應用程序屬性application.properties。
- 打包在 jar 內的應用程序屬性application.properties(和 YAML 變體)。
- @PropertySource類上的註釋@Configuration。Environment請注意,在刷新應用程序上下文之前,不會將此類屬性源添加到中。現在配置某些屬性爲時已晚,例如在刷新開始之前讀取的logging.和。spring.main.
- 默認屬性(由設置指定SpringApplication.setDefaultProperties)。
其中就有操作系統環境變量,而使用方式就是大寫和下劃線作爲分隔符,具體細節大家看鏈接的官網就明白了。
通過以上深入的腳本解析,開發者應能更加熟練地操縱Apache DolphinScheduler,從而提升數據工作流的效率和穩定性。隨着技術的不斷進步,瞭解並掌握這些基本的腳本操作對於保持技術競爭力是至關重要的。
本文由 白鯨開源科技 提供發佈支持!