继我们被apache linkis社区翻牌子以后,收录了几篇文章,今天被小海豚社区官方翻牌子了哈,当然我们也有flink社区的大佬,贡献flink社区文章若干,那就今天继续更新一篇小海豚的文章哈,本文章来自涤生大数据老师,阿里巴巴技术大佬贡献
Ambari集成大数据组件系列
1.背景
DolphinScheduler本来提供了Ambari的安装程序,可以直接集成的。但是呢,Amabri停止维护了,DS对应的安装代码也就没再更新了。DS最新版本已经到3.x了,但是安装部署脚本依旧停留在DS1.3.8,这太Low了,一点都不适用。对此,咱们就来改改,来实现DS3.x在Ambari下的集成实现。
部署环境:Aliyun Linux 2.x(Centos7.x)
2.RPM制作
安装的方式有很多,但是个人还是比较喜欢AMbari的安装风格rpm,对此,依旧沿用此方法,先把我们的安装包封装成RPM。
2.1软件包准备
官网下载对应的软件包信息,切记!!不要选最新版本的,选次新版本。别问,问就是血的教训。
#下载地址
https://dolphinscheduler.apache.org/zh-cn/download
截止2023年4月,最新版本为3.1.5,咨询了社区那些,相对比较稳定的版本是3.1.2,对此,我们选择3.1.2来进行实际环境的安装。此处,我们需要进行rpmrebuild的环境的制作,可参考百度rpmbuild的使用。然后,将我们的DS软件,解压并拷贝到对应的编译目录,待用。特殊说明:
1.安装目录软件
后续的安装目录,沿用HDP的路径:
/usr/hdp/3.3.1.0-001/dolphinscheduler;
2.编译目录
rpmbulid打包成rpm时候用到的目录,主目录在
/root/rpmbuild/BUILDROOT/;
3.软件包目录
apache-dolphinscheduler-3.1.2-1.x86_64;
4.软件包内的安装目录
/usr/hdp/3.3.1.0-001/dolphinscheduler;
所以,整体的DS的解压完整的路径是:
/root/rpmbuild/BUILDROOT/apache-dolphinscheduler-3.1.2-1.x86_64/usr/hdp/3.3.1.0-001/dolphinscheduler
2.2SPEC文件编辑
SPEC文件,是RPM制作的说明文件,我们可以完全自己写,也可以抄一个现有的。对于看这个文档的小伙伴,直接抄我的即可。完整的内容如下:
# rpmrebuild autogenerated specfile
BuildRoot: /root/.tmp/rpmrebuild.15841/work/root
AutoProv: no
%undefine __find_provides
AutoReq: no
%undefine __find_requires
# Do not try autogenerate prereq/conflicts/obsoletes and check files
%undefine __check_files
%undefine __find_prereq
%undefine __find_conflicts
%undefine __find_obsoletes
# Be sure buildpolicy set to do nothing
%define __spec_install_post %{nil}
# Something that need for rpm-4.1
%define _missing_doc_files_terminate_build 0
#dummy
#dummy
#BUILDHOST: ambaritest-vbj01c-2
#BUILDTIME: Tue Mar 15 15:06:49 2022
#SOURCERPM: apache-dolphinscheduler-2.0.1-2.src.rpm
#RPMVERSION: 4.11.3
#OS: linux
#SIZE: 245615802
#ARCHIVESIZE: 245813056
#ARCH: noarch
BuildArch: x86_64
Name: apache-dolphinscheduler
Version: 3.1.2
Release: 2
License: (c) The Apache Software Foundation
Group: apache
Summary: dolphinscheduler-dist
Distribution: apache dolphinscheduler rpm
URL: https://www.apache.org/
Vendor: The Apache Software Foundation
Packager: dolphinscheduler
Provides: apache-dolphinscheduler = 3.1.2
Requires: /bin/sh
Requires: /bin/sh
Requires: /bin/sh
Requires: /bin/sh
#suggest
#enhance
%description
Dolphin Scheduler is a distributed and easy-to-expand visual DAG workflow scheduling system, dedicated
to solving the complex dependencies in data processing, making the scheduling system out of the box for data
processing.
%files
/usr/hdp/3.3.1.0-001/dolphinscheduler
/var/run/dolphinscheduler
/var/log/dolphinscheduler
%pre -p /bin/sh
mkdir -p /usr/hdp/3.3.1.0-001/dolphinscheduler
mkdir -p /var/run/dolphinscheduler
mkdir -p /var/log/dolphinscheduler
%post -p /bin/sh
%postun -p /bin/sh
rm -rf /usr/hdp/3.3.1.0-001/dolphinscheduler
rm -rf /var/run/dolphinscheduler
%changelog
里面的具体内容与细节,参考《RPMSEPC文件解读》,此处不在复述,能用就行了,要啥自行车。说明下,这个rpm的SPEC内容,是用DS官网的1.3.8版本RPM包改的。
2.3rpm制作
有了rpm包信息,有了SPEC说明文件,剩下的就简单了,直接使用rpmbulid-bb进行编辑即可。
[root@bigdata ~]# rpmbuild -bb /root/rpmbuild/SPECS/dolphinscheduler_1.spec
剩下的交给时间即可。
我们的rpm信息就制作完成了,在HDP的repo目录,创建一个dolphinscheduler的目录,拷贝进去
[root@bigdata ~]# cp /root/rpmbuild/RPMS/x86_64/apache-dolphinscheduler-3.1.2-3.x86_64.rpm /var/www/html/ambari/HDP/centos7/3.3.1.0-001/dolphinscheduler/
[root@bigdata ~]# cd /var/www/html/ambari/HDP/centos7/3.3.1.0-001/
[root@bigdata ~]# creatrepo ./
最后用yum验证下,是否能够正确识别到。
[root@bigdata ~]# yum list |grep apache-dolphinscheduler
apache-dolphinscheduler.x86_64 3.1.2-3 HDP-3.3-repo-1
2.4长久之计
问题来了,如果下次DS升级版本,或者添加什么内容的。那么就需要重新制作RPM,以上操作再来一次。很明显,这种B格一看就不是大佬的作风。要玩,就长久点,代码能搞的,咱们就不动手。(有同样功能的,参考bigtop)我们的目的,是在DS有更新后,能够自动创建更新,创建rpm信息。自动检测一看就比较难,而且价值不大,咱们就不做了。我们把2.1-2.3的步骤全部自动化,还是有十分可观的价值的。
首先,需要解决如下几个问题:
· 编译目录:
/root/rpmbulid/BULIDROOT/.. ,这个目录下的文件回自动删除,我们每次构建都需要创建一次。
· 多版本支持,能不能每次自动更新release信息,自动保存历史记录。
带着疑惑,咋们就开始出发。
· 首先第一点,解决缓存文件被删除,无长久保存的问题。关于这个问题,从两方面进行考虑:1. 创建一个长久地址,每次封装的时候,拷贝次文件夹的内容来生成临时目录;2. 修改spec内容中的file部分,不写详细的文件列表,只写目录即可(2.2 已经修改)。
· 再然后就是release的更新了。这个就简单了,分为现有版本的获取与SPEC的更新。获取可以通过扫描repo中的文件列表,提取固定字段来获取。比如:
apache-dolphinscheduler-3.1.2-3.x86_64.rpm中的3就是Relase的版本,查询 + 排序即可搞定。Relase的替换,也简单,拿到这个数字后,加1后,使用sed命令来进行替换即可。
最后,再来自己加点难度。比如,最好适用hdp的其他程序,和变量相关的,丢前面。尽量使用函数进行封装等。
接下来,上完整代码
#!/bin/bash
# 用于ambari管理平台自动打包dolphinscheduler程序。
#===============
#定义运行环境地址
#----------------
rpm_file_path="/var/www/html/ambari/HDP/centos7/3.3.1.0-001/dolphinscheduler"
buildroot_dir="/root/rpmbuild/BUILDROOT"
src_path="/var/www/html/ambarisrc/rpm/dolphinscheduler"
version="3.1.2"
spec_dir="/root/rpmbuild/SPECS/dolphinscheduler"
#===============
# 获取各种运行变量信息
#----------------
# 获取版本信息
old_release_num=$(ls ${rpm_file_path} |grep dolphinscheduler |grep ${version} |awk -F '-' '{print $NF}'|awk -F '.' '{print $1}' |sort |tail -n 1)
release_num=$((old_release_num+1))
os_type=$(uname -a |awk '{print $12}')
function spec_config() {
#通过变量获取rpm名
rpm_file_name=$1
spec_file_name=${rpm_file_name}_${release_num}".spec"
#获取spec信息
if [ ${spec_dir}/${spec_file_name} ];then
rm -rf ${spec_dir}/${spec_file_name}
fi
cp ${spec_dir}/${rpm_file_name}.spec ${spec_dir}/${spec_file_name}
#更新release版本信息
sed -i "s/^Release:.*/Release: ${release_num}/g" ${spec_dir}/${spec_file_name}
}
function buildroot_init() {
#初始化最初的代码目录,只运行一次
#源代码目录地址:/var/www/html/ambarisrc/rpm/dolphinscheduler
cd ${src_path}
for rpm_file_list in $(ls ${rpm_file_path}|grep ${version})
do
#获取release 版本信息
rpm_file_name=$(echo ${rpm_file_list} |awk -F "-${version}" '{print $1}')
echo ${rpm_file_name}
mkdir -p ${src_path}/${rpm_file_name};cd ${src_path}/${rpm_file_name}
rpm2cpio ${rpm_file_path}/${rpm_file_name}-${version}-${old_release_num}.${os_type}.rpm |cpio -idv
done
}
function buildroot_create() {
#生成对应的编辑目录
echo "获取软件包名为: ${rpm_file_name}"
rpm_file_name=$1
rpm_buildroot_dir=${rpm_file_name}-${version}-${release_num}.${os_type}
echo "软件包编译安装名:$buildroot_dir/$rpm_buildroot_dir"
if [ ! -z ${buildroot_dir}/${rpm_buildroot_dir} ];then
mkdir ${buildroot_dir}/${rpm_buildroot_dir}
#使用现有rpm包信息,直接覆盖
fi
cd ${buildroot_dir}/${rpm_buildroot_dir}
echo "使用更新代码替换原有包信息:${src_path}/${rpm_file_name} ${buildroot_dir}/${rpm_buildroot_dir}"
cp -raf ${src_path}/${rpm_file_name}/* ${buildroot_dir}/${rpm_buildroot_dir}
echo "执行编译命令:rpmbuild -bb ${spec_dir}/${rpm_file_name}_${release_num}.spec"
rpmbuild -bb ${spec_dir}/${rpm_file_name}_${release_num}".spec"
echo "拷贝编译包更新到yum源:${rpm_file_path}"
cp /root/rpmbuild/RPMS/${os_type}/${rpm_file_name}-${version}-${release_num}.${os_type}.rpm ${rpm_file_path}
}
for rpm_file_name in $(ls ${rpm_file_path} |grep ${version} |awk -F "-${version}" '{print $1}' |uniq)
do
#spec配置生成
spec_config ${rpm_file_name}
buildroot_create ${rpm_file_name}
done
cd ${rpm_file_path}/../
createrepo ./
?
代码解读:第一段:各种变量的定义,如果其他程序,改路径和版本即可。比如ambari的打包,修改配置如下
rpm_file_path="/var/www/html/ambari/ambari/centos7/2.7.6.3-0/ambari"
buildroot_dir="/root/rpmbuild/BUILDROOT"
src_path="/var/www/html/ambarisrc/rpm/ambari"
version="2.7.6.0"
spec_dir="/root/rpmbuild/SPECS/ambari"
第二段:获取版本信息。获取现在的最新版本信息;函数:spec_config。此函数,先拷贝一个模板spec文件,步骤2.2做好的东西,然后使用sed进行版本的替换
sed -i "s/^Release:.*/Release: ${release_num}/g" ${spec_dir}/${spec_file_name}
函数:buildroot_initx0;这个是为了方便创建永久保存的目录:${src_path}。就第一次运行的时候运行;
函数:buildroot_createx0;,进行rpm的封装。从${src_path}路径拷贝最新的文件到缓存目录,然后运行rpmbuild-bb进行实际rpm的制作;
整体函数使用for循环,进行文件列表循环,以适应多个包的更新;
最后的最后:更新rpm信息:createrepo./演示示例:
有了此代码后,更新就简单多了。比如我们想修改DS的存储为Mysql,需要添加mysql-connection-java.jar到DS各个程序的lib中。
首先第一步,下载jar包:
mysql-connector-java-8.0.26.jar
第二步:拷贝此jar包到alert-server/libs,api-server/libs,master-server/libs,worker-server/libs
第三步:运行程序。就会自动封装:
apache-dolphinscheduler-3.1.2-4.x86_64.rpm
3.Dolphin集成
为了调试DS的安装,本人按照官网的安装教程,使用自带的安装程序install.shN次后得出的结论。有兴趣的小伙伴,可以自己折腾下。
3.1DS服务架构
盗的一个架构图,一看就比较复杂。
?
不过从图中可以看出,有ZK,有API、UI、DB、Alert、Master、Worker。这些,其实就是我们安装部署过程中需要运行的程序。安装DS前,需要有ZK集群以及一个Mysql。UI页面是封装到API中的,后面的Alert,Master,Worker每个作为单独的程序来运行。那么对于我们自动化部署,就是要实现DS的四个程序的启动。
3.2代码结构
有了架构图,大概对这个软件有了大概的意思,但是这东西来得不实际,很飘。涉及到具体部署的时候,拿来没啥用。最有用的,还是看安装的压缩包。第一层目录,直接拆分了角色了,一下就清爽多了,一看就懂了,每个角色程序,一个文件夹。
[root@bigdata-pricloud-mirrors dolphinscheduler]# ll
总用量 184
drwxr-xr-x. 5 root root 4096 4月 12 16:12 alert-server
drwxr-xr-x. 6 root root 4096 4月 12 16:12 api-server
drwxr-xr-x. 3 root root 4096 4月 7 16:05 bin
-rw-r--r--. 1 root root 53845 4月 7 16:05 LICENSE
drwxr-xr-x. 4 root root 20480 4月 7 16:05 licenses
drwxr-xr-x. 5 root root 4096 4月 12 16:12 master-server
-rw-r--r--. 1 root root 77523 4月 7 16:05 NOTICE
drwxr-xr-x. 5 root root 4096 4月 21 11:56 standalone-server
drwxr-xr-x. 6 root root 4096 4月 7 16:05 tools
drwxr-xr-x. 4 root root 4096 4月 7 16:05 ui
drwxr-xr-x. 5 root root 4096 4月 12 16:12 worker-server
随便进一个角色的目录:api-server
[root@bigdata-pricloud-mirrors api-server]# ll
总用量 36
drwxr-xr-x. 2 root root 4096 4月 7 16:05 bin
drwxr-xr-x. 2 root root 4096 4月 7 16:05 conf
drwxr-xr-x. 2 root root 24576 4月 7 16:05 libs
lrwxrwxrwx. 1 root root 25 4月 12 16:11 logs -> /var/log/dolphinscheduler
drwxr-xr-x. 4 root root 4096 4月 7 16:05 ui
[root@bigdata-pricloud-mirrors api-server]# ll bin/
总用量 4
-rw-r--r--. 1 root root 1400 4月 7 16:05 start.sh
[root@bigdata-pricloud-mirrors api-server]# ll conf/
总用量 32
-rw-r--r--. 1 root root 6198 4月 7 16:05 application.yaml
-rw-r--r--. 1 root root 987 4月 7 16:05 bootstrap.yaml
-rw-r--r--. 1 root root 5797 4月 7 16:05 common.properties
-rw-r--r--. 1 root root 2879 4月 7 16:05 dolphinscheduler_env.sh
-rw-r--r--. 1 root root 2587 4月 7 16:05 logback-spring.xml
-rw-r--r--. 1 root root 1385 4月 7 16:05 task-type-config.yaml
和这个角色相关的东西,大体有以下目录:
bin/start.sh
#启动命令,写死了,每个下面的,都是单独起单个进程的。比如,api下的,就是起api-server的
libs
#下面是一堆依赖文件
conf
#下面是一堆配置文件,具体的配置信息,后面实现的时候来分析
logs
#日志目录,这个不要改,不要改,改了地址后,没法在线刷新日志。但是可以用超链接换到其他地方。
ui
#这个只有api有,其他的没有。
这样的目录结构,conf、bin 目录下的文件,在不同的服务目录下面,都是一样,一样的。只需要根据不同的内容,改配置即可。
除了服务以外,还有一个特殊的目录bin/env,这个下面有两个文件,在安装的时候需要进行配置的修改,用于安装,初始化的时候需要,也要做对应的修改。
[root@bigdata ]# ll bin/env/
总用量 8
-rwxr-xr-x. 1 root root 2879 4月 7 16:05 dolphinscheduler_env.sh
-rwxr-xr-x. 1 root root 3816 4月 7 16:05 install_env.sh
3.3安装实现
目录结构看完了,部署大体结构也知道了,接下来就要开始进行实际的自动化实现了。
3.3.1服务定义:metainfo.xml
这个是定义服务的程序,定义软件版本,安装的包信息,以及配置依赖信息。此处只贴了些案例,没贴全。模块一:服务定义
DOLPHIN
Dolphin Scheduler
分布式易扩展的可视化DAG工作流任务调度系统
3.1.2
这个的效果图,在服务添加页面展示:
?
模块二:程序定义
主要定义包含哪些程序,以及程序的维护程序,定义等等各种东西,一共有四个:DOLPHIN_MASTER,DOLPHIN_WORKERx0;,DOLPHIN_APIx0;,DOLPHIN_ALERTx0;。单个参考如下,具体细节百度知。
DOLPHIN_MASTER
DS Master
MASTER
1+
PYTHON
600
模块三:安装rpm定义
这边定义需要安装的rpm程序,以及系统。我们这里能支持的是Centos7.x/8.x,Redha7.x/8.x,KylinV10,Anolis8.x,直接写个any先用着吧。
any
apache-dolphinscheduler*
剩下的,还有点内容,后期加吧,这里贴一个完成的图。
2.0
DOLPHIN
Dolphin Scheduler
分布式易扩展的可视化DAG工作流任务调度系统
3.1.2
DOLPHIN_MASTER
DS Master
MASTER
1+
PYTHON
600
DOLPHIN_WORKER
DS Worker
SLAVE
1+
PYTHON
600
DOLPHIN_ALERT
DS Alert
SLAVE
1+
PYTHON
600
DOLPHIN_API
DS Api
SLAVE
1+
PYTHON
600
ZOOKEEPER
any
apache-dolphinscheduler*
dolphin_env
common.properties
dolphin-jvm
theme.json
true
quicklinks
quicklinks.json
true
3.3.2程序安装:master_install.py
上面服务定义好了,接下来就进行软件的安装流程。就是看服务定义中的“
scripts/dolphin_master_service.pyx0;”程序内容。这个里面呢,就是定义各个软件的安装与启动程序。以下,是经过N多次改版过后的实际安装代码。
# -*- coding: utf-8 -*-
import time
from resource_management import *
from dolphin_env import dolphin_env
class DolphinMasterService(Script):
def install(self, env):
import params
env.set_params(params)
self.install_packages(env)
with open("/etc/passwd") as f:
userlist = []
for line in f:
line=line.strip()
vec =line.split(':')
userlist.append(vec[0])
if params.dolphin_user in userlist:
Logger.info("Dolphin Deploy User : " + params.dolphin_user + "already exists ")
else:
Execute(('useradd', params.dolphin_user))
Execute(('sed -i \'/^' + params.dolphin_user + '/d\' /etc/sudoers'))
Execute(('sed -i \'$a' + params.dolphin_user + ' ALL=(ALL) NOPASSWD: NOPASSWD: ALL\' /etc/sudoers'))
Execute(('mkdir -p ' + " " + params.dolphin_home))
Execute(('mkdir -p ' + " " + params.dolphin_log_dir))
Execute(('mkdir -p ' + " " + params.dolphin_pidfile_dir))
Execute(('chown -R ' + params.dolphin_user + ":" + params.dolphin_group + " " + params.dolphin_home))
Execute(('chown -R ' + params.dolphin_user + ":" + params.dolphin_group + " " + params.dolphin_log_dir))
Execute(('chown -R ' + params.dolphin_user + ":" + params.dolphin_group + " " + params.dolphin_pidfile_dir))
Execute(('chown -R ' + params.dolphin_user + ":" + params.dolphin_group + "/var/log/dolphinscheduler"))
Execute(('rm -f ' + " " + params.dolphin_home+"/master-server/conf/core-site.xml"))
Execute(('ln -s /etc/hadoop/conf/core-site.xml' + " " + params.dolphin_home+"/master-server/conf/core-site.xml"))
Execute(('rm -f ' + " " + params.dolphin_home+"/master-server/conf/hdfs-site.xml"))
Execute(('ln -s /etc/hadoop/conf/hdfs-site.xml' + " " + params.dolphin_home+"/master-server/conf/hdfs-site.xml"))
def configure(self, env):
import params
params.pika_slave = True
env.set_params(params)
dolphin_env()
def start(self, env):
import params
env.set_params(params)
self.configure(env)
Execute(('sed -i \'/^' + params.dolphin_user + '/d\' /etc/sudoers'))
Execute(('sed -i \'$a' + params.dolphin_user + ' ALL=(ALL) NOPASSWD: NOPASSWD: ALL\' /etc/sudoers'))
no_op_test = format("ls {dolphin_pidfile_dir}/master-server.pid >/dev/null 2>&1 && ps `cat {dolphin_pidfile_dir}/master-server.pid` | grep `cat {dolphin_pidfile_dir}/master-server.pid` >/dev/null 2>&1")
start_cmd = format("sh " + params.dolphin_bin_dir + "/dolphinscheduler-daemon.sh start master-server")
Execute(start_cmd, user=params.dolphin_user, not_if=no_op_test)
def stop(self, env):
import params
env.set_params(params)
stop_cmd = format("sh " + params.dolphin_bin_dir + "/dolphinscheduler-daemon.sh stop master-server")
Execute(stop_cmd, user=params.dolphin_user)
time.sleep(5)
def status(self, env):
import params
env.set_params(params)
check_process_status(params.dolphin_pidfile_dir + "/master-server/pid")
if __name__ == "__main__":
DolphinMasterService().execute()
具体内容,其中,服务安装的程序在下面代码的:install_packages中,会根据3.1.1中,os处定义的内容,来进行rpm包的安装,此处实际执行命令:
yuminstall-yapache-dolphinscheduler*
def install(self, env):
import params
env.set_params(params)
self.install_packages(env)
其他安装程序,类似,只是需要修改对应的路径和文件名信息
?
特殊说明下,最开始的程序,需要做系统的初始化,沿用1.3.8版本的初始化逻辑,把数据库的初始化放在api的启动程序中:dolphin_api_service.pyx0;
def start(self, env):
import params
env.set_params(params)
self.configure(env)
Execute(('sed -i \'/^' + params.dolphin_user + '/d\' /etc/sudoers'))
Execute(('sed -i \'$a' + params.dolphin_user + ' ALL=(ALL) NOPASSWD: NOPASSWD: ALL\' /etc/sudoers'))
#init
init_cmd=format("sh " + params.dolphin_home + "/tools/bin/upgrade-schema.sh")
Execute(init_cmd, user=params.dolphin_user)
no_op_test = format("ls {dolphin_pidfile_dir}/api-server.pid >/dev/null 2>&1 && ps `cat {dolphin_pidfile_dir}/api-server.pid` | grep `cat {dolphin_pidfile_dir}/api-server.pid` >/dev/null 2>&1")
start_cmd = format("sh " + params.dolphin_bin_dir + "/dolphinscheduler-daemon.sh start api-server")
Execute(start_cmd, user=params.dolphin_user, not_if=no_op_test)
3.4配置管理
你以为上面写好就能用了?肤浅了,格局一定要打开。安装才是第一步,怎么做配置的更新、管理才是一个好的部署平台。最好自动化安装,点一下需要安装的程序,剩下的全部根据集群,系统来默认最优配置设置,这才是一个大佬应该写出来的自动化程序。其实,3.3中的程序,已经包含了配置的更新,其中,每个控制模块前的importparams和set-params即配置的读取与更新程序。
def install(self, env):
import params
env.set_params(params)
以上代码,对应的程序
3.4.1配置解读
在我N多次的安装、卸载,对比配置等各个操作手段后,得出了以下内容。需要修改的配置内容如下,以ds的安装相对路径进行文件的书写。
#各种允许环境的指定,以及DB的环境信息,其他环境全部通用。
./bin/env/dolphinscheduler_env.sh
#各种软件角色地址的部署地址信息。以及一些hdfs的配置...
./bin/env/install_env.sh
#各个服务相关的配置,定义数据库信息,ZK信息,以及端口信息。
./api-server/conf/application.yaml
#这个组件里面的配置不同
./api-server/conf/bootstrap.yaml
#启动程序名的定义,这个不需要做任何修改。
./api-server/conf/common.properties
#主要的配置信息,数据库,存储地址啊,等等相关的。
./api-server/conf/logback-spring.xml
#日志路径相关的,不用改内容,尝试改过,然后功能不正常了。所以还是用超链接来实现log的修改吧。
./api-server/conf/task-type-config.yaml
#支持的调度定义,默认即可。
差不多,这些配置都得改吧。
3.4.2confiuration配置管理
对于配置相关的管理,在Amabri中,是通过一个叫configuration相关的xml进行设置的。这里以dolphin-env.xml比如配置
./bin/env/dolphinscheduler_env.sh中的一个配置
# Database related configuration, set database type, username and password
export DATABASE=${DATABASE:-mysql}
export SPRING_PROFILES_ACTIVE="dolphin"
export SPRING_DATASOURCE_URL="jdbc:mysql://127.0.0.1:3306/pricloud_dolphin?useUnicode=true&characterEncoding=UTF-8&useSSL=false"
export SPRING_DATASOURCE_USERNAME="admin"
export SPRING_DATASOURCE_PASSWORD="password"
其中在configuration中的相关定义如下:
dolphin.database.type
mysql
选择海豚调度的数据库类型:Mysql/PG 2选一,默认Mysql
数据库类型
value-list
mysql
postgresql
1
dolphin.database.db
dolphin
数据库名
特殊说明,这种类型不太一样,数据库类型提供的是一个多选,提供mysql个PG的单选按钮,数据库是一个字符串,不用高级设置。成品大概如下:
?
?
特殊说明下,我是代码搞好后再写的文档,截图和xml中的定义,不太一样。
3.4.2params配已置读取
接下来,数据的定义有了,那就需要进行数据的读取了,在web页面,如果修改了配置,需要将这个配置写入到具体的配置文件中。怎么来读取这个配置呢?这个写入在脚本parms.py中,先来一个案例:
#==================================
# dolphin env
#==================================
dolphin_database_type = config['configurations']['dolphin-env']['dolphin.database.type']
dolphin_database_db = config['configurations']['dolphin-env']['dolphin.database.db']
dolphin_database_username = config['configurations']['dolphin-env']['dolphin.database.username']
dolphin_database_password = config['configurations']['dolphin-env']['dolphin.database.password']
if 'mysql' == dolphin_database_config['dolphin_database_type']:
dolphin_database_config['dolphin_database_url'] = 'jdbc:mysql://'...
dolphin_database_driver = 'com.mysql.cj.jdbc.Driver'
driverDelegateClass = 'org.quartz.impl.jdbcjobstore.StdJDBCDelegate'
dolphin_database_url = 'jdbc:mysql://'...
else:
dolphin_database_config['dolphin_database_driver'] = 'org.postgresql.Driver'
dolphin_database_config['driverDelegateClass'] = 'org.quartz.impl.jdbcjobstore.PostgreSQLDelegate'
dolphin_database_config['dolphin_database_url'] = 'jdbc:postgresql://'...
案例解读,这里就是定义各种变量信息的。比如读取“dolphin-envx0;.xml”中关于mysql类型的定义为:
dolphin_database_type = config['configurations']['dolphin-env']['dolphin.database.type']
玩得再花一点,就再写点判断,这样就可以根据一个选择来进行不同数据的定义。除了这种定义的以外,还有和集群相关的配置,比如ZK相关的,可以根据ZK集群的信息,自动读取ZK配置,具体写法如下:
ZookeeperServerHostInfo = config['clusterHostInfo']['zookeeper_server_hosts']
if len(ZookeeperServerHostInfo) > 0 and "clientPort" in config["configurations"]['zoo.cfg']:
clientPort = config['configurations']['zoo.cfg']['clientPort']
zookeeperPort = ":" + clientPort + ","
dolphin_registry_addr = zookeeperPort.join(ZookeeperServerHostInfo) + ":" + clientPort
Logger.info("dolphin_registry_addr : " + str(dolphin_registry_addr))
剩下的,自己更具配置的内容添加即可。
3.4.3Templates模板生成
数据配置定义了,数据配置的方法读取方法获取了,接下来,问题来了:怎么把这些信息写入到具体配置里面呢?这里,使用Templates模板来进行配置文档的编辑。此处核心就是配置使用{{变量名}}来进行替换首先用application.yaml来打个样。
spring:
config:
activate:
on-profile: {{application_jdbc_type}}
datasource:
driver-class-name: {{application_jdbc_driver}}
url: {{application_jdbc_url}}
username: {{application_jdbc_username}}
password: {{application_jdbc_password}}
其中:{{application_jdbc_type}}等,都是parms.py中进行的变量获取。整体套路就是这样,剩下的就是对比不同的配置,来制作多个模板。全部的信息如下:
?
这里只是完成了一半,另外的一半,需要定义这些模板文件,需要写到哪些配置里面。这里的话,写在了dolphin_env.py中,这里面主要进行文件夹的创建,以及配置的更新。
def dolphin_env():
import params
Directory(params.dolphin_pidfile_dir,
mode=0755,
owner=params.dolphin_user,
group=params.dolphin_group,
create_parents=True
)
File(format(params.dolphin_home + '/alert-server/conf/application.yaml'),
mode=0644,
content=Template("application-alter.yaml.j2"),
owner=params.dolphin_user,
group=params.dolphin_group
)
File(format(params.dolphin_home + '/api-server/conf/application.yaml'),
mode=0644,
content=Template("application-api.yaml.j2"),
owner=params.dolphin_user,
group=params.dolphin_group
)
以上为案例,一看就懂,不做解释。剩下的就是体力劳动。到此,已经可用了,写到这里,自动化部署就已经完成了。但是,还是那句话,格局一定要打开,要最求卓越。
?
3.5themes视觉优化
以下两个图,那个好看?很明显,不做选择题,咋们全都要。只是,上图已经实现了,接下来进行下图的实现。
?
?
其中,下图的内容需要使用到的是Ambari提供的Themes模板,类似于一个页面编辑框的工具,可以将单单选,多选文本的换个花样来展示。
3.5.1themes解读
首先来看看themes的写法,大概长这样的,主题包含三个目录。layouts,placement和widgets
{
"name": "default",
"description": "Default theme for Dolphin Scheduler service",
"configuration": {
"layouts": [
{
"name": "default",
"tabs": [
{
"name": "settings",
"display-name": "Settings",
"layout": {
"tab-rows": "4",
"tab-columns": "3",
"sections": [
{
"name": "dolphin-env-config",
"display-name": "海豚环境配置",
"row-index": "0",
"column-index": "0",
"row-span": "1",
"column-span": "2",
"subsections": [
{
"name": "env-row1-col1",
"display-name": "部署用户信息",
"row-index": "0",
"column-index": "0",
"row-span": "1",
"column-span": "1"
},...
],
"placement": {
"configuration-layout": "default",
"configs": [
{
"config": "dolphin-env/dolphin.user",
"subsection-name": "env-row1-col1"
}
...
]
},
"widgets": [
{
"config": "dolphin-env/dolphin.user",
"widget": {
"type": "text-field"
}
layouts:是对整体页面做拆分,做页面排布。并对每个页面命名和编号。页面的布局内容如下:
?
placement,是对定义在框框中,填入什么样的内容。比如JVM处,大题填以下内容:
?
widgets,则是定义数据的规范,和显示的格式,这个需要和对应的xml中的配置遥相呼应。比如:text-fieldx0;文本框,就是单纯的框框格式,比如环境配置信息的
?
togglex0; 二选一的拖拽框,比如,是否开启kerbers配置的选项
?
combox0;,下拉框,用于多选一的选择,比如数据库类型,文件存储类型等。
大体介绍完了,接下来进行实际的实现。
3.5.2目录配置
我们在最开始的地方<0,0>来进行环境配置的设置。打算提供,用户账号、组,以及环境变量的定义。这里采用的是大框套小框来进行实现的,整体页面布局就,及其对应的编码就变成了这样。
?
接下来就进行具体的框框的定义。在configurationx0;.layoutsx0;.tabs.x0;sectionsx0;处进行定义,从外部定义到内部,逐级定义。
{
"name": "dolphin-env-config",
"display-name": "海豚环境配置",
"row-index": "0",
"column-index": "0",
"row-span": "1",
"column-span": "2",
"subsections": [
{
"name": "env-row1-col1",
"display-name": "部署用户信息",
"row-index": "0",
"column-index": "0",
"row-span": "1",
"column-span": "1"
}
接下来,定义这个框里面需要输入的数据:账号、组,以及环境变量;在配置位置:configurationx0;.placementx0;x0;.configsx0;
"placement": {
"configuration-layout": "default",
"configs": [
{
"config": "dolphin-env/dolphin.user",
"subsection-name": "env-row1-col1"
},
{
"config": "dolphin-env/dolphin.group",
"subsection-name": "env-row1-col1"
},
{
"config": "dolphin-env/dolphinscheduler-env-content",
"subsection-name": "env-row1-col1"
}
最后,定义处这些内容的数据展示格式。在配置configuration.widgetsx0;处
"widgets": [
{
"config": "dolphin-env/dolphin.user",
"widget": {
"type": "text-field"
}
},
{
"config": "dolphin-env/dolphin.group",
"widget": {
"type": "text-field"
}
},
{
"config": "dolphin-env/dolphinscheduler-env-content",
"widget": {
"type": "text-area"
}
},
这里都是text格式,对应的一个xml案例,dolphin-env.xml关于部署用户dolphin.user的定义。
dolphin.user
dolphin
安装哪个用户并管理海豚调度器
部署用户
通过以上,操作,最后的效果图如下。
?
3.5.2JVM配置
同上,依旧来进行JVM的设置,复制3.5.1开头的内容,先来进行JVM的位置信息设置。他的位置是<0,1>;
{
"name": "env-row1-col2",
"display-name": "JVM信息配置",
"row-index": "0",
"column-index": "1",
"row-span": "1",
"column-span": "1"
}
接下来进行对应数据的填充与设置,同上,这里只提供一些参数的设置,其他的,参考排布即可。
{
"config": "dolphin-jvm/alert.jvm.xmx",
"subsection-name": "env-row1-col2"
},
{
"config": "dolphin-jvm/api.jvm.xmx",
"subsection-name": "env-row1-col2"
},
与上图不同的是,这里采用拉条的方式来进行数据的数据的设置,左右横拉,实现JVM的设置。其中,在themes中的数据定义如下:
{
"config": "dolphin-jvm/alert.jvm.xmx",
"widget": {
"type": "slider",
"units": [
{
"unit-name": "GB"
}
]
}
},
对应的xml信息,在配置dolphin-jvm.xml中,每次可调节1G大小,允许设置的范围为1-4G,可以根据具体的配置设置。
alert.jvm.xmx
1
Alert JVM大小
Alert 预分配的JVM使用的最大内存量
如果您希望输入一个高于滑块上最大值的值,请单击鼠标悬停在设置上时出现的铅笔,并忽略不建议输入更高的值。
int
1
4
1
GB
最后效果案例效果。
?
3.5.3数据库配置
数据库的,同上。不整废话,都一样的东西。效果图如下:
?
3.5.4存储类型选择
数据存储类型的时候,这个有点不同了,因为添加了可选,并且可选进行数据内容的展示。先来看效果图:
?
?
选择HDFS为存储后,对应的配置如图左上;选择Null的效果如右上;AwsS3及其同类产品的如左下;阿里云OSS的如右下。这个是怎么实现的呢?关于图表框的定义,同上。不在叙述。接下来就是关于具体内容的选择,这里设置不一样了。首选,下拉框,选择存储格式,下面定义数据的输入
{
"config": "common.properties/resource.storage.type",
"subsection-name": "dynamic-row1-col1"
}
对应的数据格式为:
{
"config": "common.properties/resource.storage.type",
"widget": {
"type": "combo"
}
}
对应的xml定义文件:common.properties.xml,这是一个多选
resource.storage.type
HDFS
资源存储类型: HDFS , S3 , OSS , NONE
资源存储类型
value-list
HDFS
S3
OSS
NONE
1
这样,下拉框就完成了。接下来,怎么根据下拉框的格式来进行相应配置的选择呢?其实,这个的重点就是判断+可显示字段的信息标记。贴代码就懂了。在数据展示处:
{
"config": "common.properties/resource.alibaba.cloud.oss.endpoint",
"subsection-name": "dynamic-row1-col1",
"depends-on": [
{
"configs":[
"common.properties/resource.storage.type"
],
"if": "${common.properties/resource.storage.type} === OSS",
"then": {
"property_value_attributes": {
"visible": true
}
},
"else": {
"property_value_attributes": {
"visible": false
}
}
}
]
},
{
"config": "common.properties/resource.hdfs.root.user",
"subsection-name": "dynamic-row1-col1",
"depends-on": [
{
"configs":[
"common.properties/resource.storage.type"
],
"if": "${common.properties/resource.storage.type} === HDFS",
"then": {
"property_value_attributes": {
"visible": true
}
},
"else": {
"property_value_attributes": {
"visible": false
}
}
}
]
},
在每个选项中,添加一个判断,只有当type类型相关的时候,显示标记位再设置是否显示。这样就完事儿了。
3.5.5Kerberos&Wechat
这两个功能还没设置好,先把功能页面开启来先。
数据框,及其框中数据编辑都同上,不在叙述。
不同就是数据的定义:
{
"config": "common.properties/hadoop.security.authentication.startup.state",
"widget": {
"type": "toggle"
}
},
{
"config": "common.properties/enterprise.wechat.enable",
"widget": {
"type": "toggle"
}
}
对应的XML数据定义,剩下的自己复制改。
hadoop.security.authentication.startup.state
false
功能未开发完毕,别开启
是否开启Kerberos认证
value-list
true
false
1
通过以上一波操作,就全部完成了themes的定义,重点配置丢这里,看起来就舒服了。这样,重点配置在Setting页面,详细配置在advance页面。
3.6超链接实现
DS给提供了Web页面,最好的话,再搞个超链接,点击即可访问。说干就看,先看效果图
?
这个功能一共需求两个东东。
第一个,服务定义metainfo.xml中,需要添加关于超链接的定义。
quicklinks.json
true
在新建文件夹quicklinks,并在下面新建文件quicklinks.json案例数据如下,具体内容,自己百度。
{
"name": "default",
"description": "default quick links configuration",
"configuration": {
"protocol":
{
"type":"http"
},
"links": [
{
"name": "dolphin-application-ui",
"label": "DolphinApplication UI",
"requires_user_name": "false",
"component_name": "DOLPHIN_API",
"url": "%@://%@:%@/dolphinscheduler/ui/",
"port":{
"http_property": "server.port",
"http_default_port": "12345",
"regex": "^(\\d+)$",
"site": "dolphin-application-api"
}
}
]
}
}
这个改起来简单,效率给力。到此,文档完毕,还有监控和告警相关的,不想写了,就是这么有脾气。不是代码不想写,而且不想写文档。因为干IT最讨厌两件事:自己写代码的时候,写备注+文档、看别人代码的时候,没备注和文档;
?
欢迎在研究大数据集群二开的朋友们来战(交流交流哈哈哈),也可以在b站上看我录制的apache hadoop集群运维实战哈