精细调度:Apache DolphinScheduler脚本深度解析
在现代数据处理和工作流管理中,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,从而提升数据工作流的效率和稳定性。随着技术的不断进步,了解并掌握这些基本的脚本操作对于保持技术竞争力是至关重要的。
本文由 白鲸开源科技 提供发布支持!
低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
如何基于容器网络流量指标进行弹性伸缩
本文分享自华为云社区《【自定义指标HPA】基于容器网络流量指标进行弹性伸缩》,作者: 可以交个朋友。 一、背景 业务程序非CPU、memeory敏感类业务,希望可以基于流量指标进行HPA弹性伸缩,但是大部分程序并没有集成Prometheus SDK相关代码进行插桩。此时可以通过cAdvisor提供的容器网络流量指标实现业务峰谷期间的弹性扩缩容。 二、方案介绍 cAdvisor负责节点上的容器和节点本身资源的统计,内置在kubelet中,并通过kubelet的/metrics/cadvisor接口对外提供API。它可以采集容器网络累积接收数据总量和容器网络累积传输数据总量,即网络流入和流出指标。 参考指标: container_network_receive_bytes_total容器接受的网络流量,单位是字节数 container_network_transmit_bytes_total容器传输的网络流量,单位是字节数 上面两个指标都是counter计数器类型,对应的值只增不减。在配置自定义指标转换规则时需要做下速率换算,将总量换算成每秒接受多少字节数的流量指标。 三、实践操作 3.1...
- 下一篇
Sermant运行流程学习笔记,速来抄作业
本文分享自华为云社区《Sermant 的整体流程学习梳理》,作者:用友汽车信息科技(上海)有限公司刘亚洲 Java研发工程师。 一、sermant架构 Sermant整体架构包括Sermant Agent、Sermant Backend、Sermant Injector、动态配置中心等组件。其中Sermant Agent是提供字节码增强基础能力及各类服务治理能力的核心组件,Sermant Backend、Sermant Injector、动态配置中心为Sermant提供其他能力的配套组件。 二、java agent和bytebuddy组合使用场景 比较典型的就是skywalking、sermant、arthas、mockito。如果说java agent开了一扇门,那么bytebuddy在开的这扇门中打开了一片新的天地。 三、Sermant的入口 前面我们说AgentLauncher是java agent的入口,为什么这么说呢? <manifestEntries> <Premain-Class>com.huaweicloud.sermant.premain...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- CentOS关闭SELinux安全模块
- CentOS7设置SWAP分区,小内存服务器的救世主
- Docker安装Oracle12C,快速搭建Oracle学习环境
- SpringBoot2全家桶,快速入门学习开发网站教程
- CentOS7编译安装Gcc9.2.0,解决mysql等软件编译问题
- Eclipse初始化配置,告别卡顿、闪退、编译时间过长
- SpringBoot2整合Thymeleaf,官方推荐html解决方案
- Docker使用Oracle官方镜像安装(12C,18C,19C)
- CentOS7编译安装Cmake3.16.3,解决mysql等软件编译问题
- CentOS8编译安装MySQL8.0.19