Azkaban的安装和使用

目录



Azkaban是一个开源的工作流管理器(Workflow Manager)。Azkaban是在LinkedIn上创建的批处理工作流作业调度程序,用于运行Hadoop作业。Azkaban通过作业依赖性解决订单,并提供易于使用的Web用户界面来维护和跟踪您的工作流程。Azkaban的设计主要考虑了可用性,它已经在LinkedIn运行了几年,并推动了许多Hadoop和数仓流程(warehouse Processes)。


1 任务调度

Linux系统本身会周期性的执行一些任务调度(例如系统缓存、系统日志等),因此Linux系统有一个专门的守护进程来负责这个任务调度(ps -ef|grep cron),我们也可以将我们自己需要调度的任务添加到Linux系统的任务调度中,这个就是Linux的Crontab。
crontab -e

[root@node3 ~]# cat /etc/crontab
SHELL=/bin/bash
PATH=/sbin:/bin:/usr/sbin:/usr/bin
MAILTO=root
# For details see man 4 crontabs
# Example of job definition:
# .---------------- minute (0 - 59)
# |  .------------- hour (0 - 23)
# |  |  .---------- day of month (1 - 31)
# |  |  |  .------- month (1 - 12) OR jan,feb,mar,apr ...
# |  |  |  |  .---- day of week (0 - 6) (Sunday=0 or 7) OR sun,mon,tue,wed,thu,fri,sat
# |  |  |  |  |
# *  *  *  *  * user-name  command to be executed

月份在日后面,这有点英式英语(Linux之父Torvalds出生于芬兰赫尔辛基市),最后是周。MAILTO指定crond任务错误时,将错误讯息发送给谁,这个可以填写一个email。例如现在有一个脚本 monitoring.sh(定时监测某个服务,如果挂了自动提起),然后每隔3分钟监测一次,可以执行 crontab -e (默认当前用户),然后插入语句,esc退出编辑,:wq保存。

*/3 * * * * /bin/bash /home/es/monitoring.sh >> /var/log/es/monitoring.log

2 Azkaban特点

  • 和Azkaban系统类似的还有Oozie,Oozie是通过编写大量规范的XML配置来实现的工作流调度的,代码复杂度较高,也不易于二次开发,相比于Azkaban来说Oozie是一个重量级的任务调度系统,对于数仓类的调调Azkaban是一个很不错的选择。其主要有如下几个特点:
  • 兼容任何版本的Hadoop
  • 友好的Web UI
  • 分布式的多执行器
  • 项目工作区
  • 调度工作流程或有条件的
  • 模块化和可插入
  • 身份验证和授权
  • 跟踪用户操作
  • 有关失败和成功的电子邮件提醒
  • SLA警报和自动查杀
  • 重试失败的工作

3 安装

Azkaban架构设计图
从上面Azkaban结构设计图可以看到Azkaban主要由三本分组成:

  • Relation Database:这里建议使用Mysql(官方文档中说目前仅支持MySQL),因为脚本中有针对Msyql的增强功能设置,azkaban将大多数状态信息都存于MySQL中,Azkaban Web Server 和 Azkaban Executor Server也需要访问DB。
  • Azkaban Web Server:提供了Web UI,是azkaban的主要管理者,包括 project 的管理,认证,调度,对工作流执行过程的监控等。
  • Azkaban Executor Server:调度工作流和任务,Azkaban执行服务器执行提交工作流

这次安装采用 Multi Executor Server方式安装。


3.1 安装前环境准备

Azkaban安装需要对源码进行编译,编译时需要环境已安装如下软件:

  • Java8或更高版本
  • Maven
  • Gradle

Java的安装和Maven的安装应该并不陌生,这里简单说下Gradle的安装:

wget http://services.gradle.org/distributions/gradle-5.4.1-bin.zip
unzip -d /usr/local/ gradle-5.4.1-bin.zip
mv /usr/local/gradle-5.4.1 /usr/local/gradle

设置gradle环境变量 vim ~/.bash_profile,保存退出并生效。然后 gradle -v 验证。

# 输入如下,保存,退出
GRADLE_HOME=/usr/local/gradle-5.4.1
export PATH=$PATH:$GRADLE_HOME/bin

3.2 编译

# clone源码。也可以下载对应版本的源码,直接编译
# wget https://github.com/azkaban/azkaban/archive/3.73.1.tar.gz
git clone https://github.com/azkaban/azkaban.git
cd azkaban
git tag
git checkout tags/3.73.1
git branch
./gradlew clean build -x test

编译中错误解决

第一次编译时没有出现错误,当最近编译时发生了如下的错误:

Starting a Gradle Daemon (subsequent builds will be faster)
Parallel execution with configuration on demand is an incubating feature.
> Task :az-exec-util:linkMainExecutable FAILED
collect2: fatal error: cannot find 'ld'
compilation terminated.
FAILURE: Build failed with an exception.
* What went wrong:
Execution failed for task ':az-exec-util:linkMainExecutable'.
> A build operation failed.
      Linker failed while linking main.
  See the complete log at: file:///opt/azkaban/az-exec-util/build/tmp/linkMainExecutable/output.txt
* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights.
* Get more help at https://help.gradle.org
BUILD FAILED in 11s
41 actionable tasks: 15 executed, 7 from cache, 19 up-to-date

查看ld,发现缺少ld命令:

[root@node1 azkaban]# whereis ld
 ld: /usr/bin/ld.bfd /usr/bin/ld.gold /usr/share/man/man1/ld.1.gz
 
 [root@node1 azkaban]#  ll /usr/bin/ld*
 -rwxr-xr-x 1 root root 1006216 Oct 30  2018 /usr/bin/ld.bfd
 -rwxr-xr-x 1 root root    5302 Jul  3 21:25 /usr/bin/ldd
 -rwxr-xr-x 1 root root 5354296 Oct 30  2018 /usr/bin/ld.gold

因此我们修复这个命令,先删除 binutils

#查看ld RPM信息
[root@node1 azkaban]# rpm -qf /usr/bin/ld
binutils-2.27-34.base.el7.x86_64
#删除这个,然后重新安装
[root@node1 azkaban]# rpm -e binutils --nodeps
admindir /var/lib/alternatives invalid
admindir /var/lib/alternatives invalid

再重新安装 binutils

#下载。http://rpmfind.net/linux/rpm2html/search.php?query=binutils,例如CentOS7下载如下包
wget http://rpmfind.net/linux/centos/7.6.1810/os/x86_64/Packages/binutils-2.27-34.base.el7.x86_64.rpm
# 安装
[root@node1 ~]# rpm -ivh binutils-2.27-34.base.el7.x86_64.rpm
Preparing...                          ################################# [100%]
Updating / installing...
   1:binutils-2.27-34.base.el7        ################################# [100%]
admindir /var/lib/alternatives invalid
admindir /var/lib/alternatives invalid
admindir /var/lib/alternatives invalid

再次查看ld,如下:

[root@node1 ~]#  ll /usr/bin/ld*
-rwxr-xr-x 1 root root 1006216 Oct 30  2018 /usr/bin/ld.bfd
-rwxr-xr-x 1 root root    5302 Jul  3 21:25 /usr/bin/ldd
-rwxr-xr-x 1 root root 5354296 Oct 30  2018 /usr/bin/ld.gold

还是没有ld ,但是不要慌,其依赖其实是已经修复,如果没有这一步,直接修复软连是会报如下的错误:

error while loading shared libraries: libbfd-2.25.1-31.base.el7.so: cannot open shared object file: No such file or directory

此时只需要从其他CentOS系统中拷贝ld,并做个软连就可以了

#从其他节点(cdh3)拷贝 alternatives
[root@cdh3 ~]# scp -r /etc/alternatives/ root@node1:/etc/alternatives

# 软连修复
[root@node1 ~]#  cd /usr/bin
[root@node1 bin]# ln -s /etc/alternatives/ld  ld
# 再次查看。
[root@node1 bin]# ls -l ld*
lrwxrwxrwx 1 root root      20 Aug 19 19:00 ld -> /etc/alternatives/ld
-rwxr-xr-x 1 root root 1006216 Oct 30  2018 ld.bfd
-rwxr-xr-x 1 root root    5302 Jul  3 21:25 ldd
-rwxr-xr-x 1 root root 5354296 Oct 30  2018 ld.gold

再次重新编译,这次OK:

[root@node1 azkaban]# ./gradlew clean build -x test
Parallel execution with configuration on demand is an incubating feature.
> Task :azkaban-common:compileJava
Note: Some input files use or override a deprecated API.
Note: Recompile with -Xlint:deprecation for details.
Note: Some input files use unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details.
> Task :azkaban-exec-server:compileJava
Note: Some input files use unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details.
> Task :azkaban-hadoop-security-plugin:compileJava
Note: Some input files use or override a deprecated API.
Note: Recompile with -Xlint:deprecation for details.
Note: /opt/azkaban/azkaban-hadoop-security-plugin/src/main/java/azkaban/security/HadoopSecurityManager_H_2_0.java uses unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details.
> Task :azkaban-web-server:npmSetup
/opt/azkaban/azkaban-web-server/.gradle/npm/npm-v5.6.0/bin/npm -> /opt/azkaban/azkaban-web-server/.gradle/npm/npm-v5.6.0/lib/node_modules
/opt/azkaban/azkaban-web-server/.gradle/npm/npm-v5.6.0/bin/npx -> /opt/azkaban/azkaban-web-server/.gradle/npm/npm-v5.6.0/lib/node_modules
+ [email protected]
added 476 packages in 10.486s
> Task :azkaban-web-server:compileJava
Note: Some input files use or override a deprecated API.
Note: Recompile with -Xlint:deprecation for details.
Note: Some input files use unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details.
> Task :az-hadoop-jobtype-plugin:compileJava
Note: Some input files use or override a deprecated API.
Note: Recompile with -Xlint:deprecation for details.
Note: /opt/azkaban/az-hadoop-jobtype-plugin/src/main/java/azkaban/jobtype/HadoopSecureSparkWrapper.java uses unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details.
> Task :azkaban-web-server:npm_install
added 39 packages in 1.293s
> Task :azkaban-solo-server:compileJava
Note: /opt/azkaban/azkaban-solo-server/src/main/java/azkaban/soloserver/AzkabanSingleServer.java uses or overrides a deprecated API.
Note: Recompile with -Xlint:deprecation for details.
> Task :az-hdfs-viewer:compileJava
Note: Some input files use or override a deprecated API.
Note: Recompile with -Xlint:deprecation for details.
> Task :az-reportal:compileJava
Note: /opt/azkaban/az-reportal/src/main/java/azkaban/reportal/util/StreamProviderHDFS.java uses or overrides a deprecated API.
Note: Recompile with -Xlint:deprecation for details.
BUILD SUCCESSFUL in 33s
93 actionable tasks: 79 executed, 8 from cache, 6 up-to-date

编译完毕后,主要关注如下编译后的分发包:

azkaban/azkaban-web-server/build/distributions/azkaban-web-server-3.73.1.tar.gz
azkaban/azkaban-exec-server/build/distributions/azkaban-exec-server-3.73.1.tar.gz
#azkaban/azkaban-db/build/distributions/azkaban-db-3.73.1.tar.gz
azkaban/azkaban-db/build/sql/create-all-sql-3.73.1.sql

3.3 初始化MySQL中的数据库和表

例如MySQL数据库在node1节点,我们需要保证MySQL支持的数据包够大,例如支持1024M,修改MySQL的配置文件 /etc/my.cnf :

[mysqld]
...
max_allowed_packet=1024M

然后重启MySQL服务:

# service mysql restart
$ sudo /sbin/service mysqld restart

初始化MySQL数据,这一步主要是在MySQL数据库中创建Azkaban库,并执行创建表的SQL脚本,将需要用到的表创建出来。

--如果数据库没有,先创建出数据库,库名随意,和后面配置文件一致即可,这里使用airflow
mysql> CREATE DATABASE airflow;
 --使用这个库
mysql> use airflow;
--将上一步编译后整理的azkaban/azkaban-db/build/sql/create-all-sql-3.73.1.sql,上传到mysql服务
--也可以解压azkaban-db-3.73.1.tar.gz获得create-all-sql-3.73.1.sql,执行建表脚本
mysql> source /app/azkaban-db-3.73.1/create-all-sql-3.73.1.sql;
mysql> show tables;
+--------------------------+
| Tables_in_airflow        |
+--------------------------+
| QRTZ_BLOB_TRIGGERS       |
| QRTZ_CALENDARS           |
| QRTZ_CRON_TRIGGERS       |
| QRTZ_FIRED_TRIGGERS      |
| QRTZ_JOB_DETAILS         |
| QRTZ_LOCKS               |
| QRTZ_PAUSED_TRIGGER_GRPS |
| QRTZ_SCHEDULER_STATE     |
| QRTZ_SIMPLE_TRIGGERS     |
| QRTZ_SIMPROP_TRIGGERS    |
| QRTZ_TRIGGERS            |
| active_executing_flows   |
| active_sla               |
| execution_dependencies   |
| execution_flows          |
| execution_jobs           |
| execution_logs           |
| executor_events          |
| executors                |
| project_events           |
| project_files            |
| project_flow_files       |
| project_flows            |
| project_permissions      |
| project_properties       |
| project_versions         |
| projects                 |
| properties               |
| triggers                 |
+--------------------------+

--提前手动插入executor的ip和端口。Azkaban默认也执行节点通信使用的是12321端口,
--如果12321端口占用,可以使用其他端口,后面配置文件修改,例如这里使用12331端口
--这一步其实可以不用插入,executor启动会自动插入,active标记为0,
--当web启动正常访问executor时会改为1,当关闭是会删除这个ip。
--这里建议手动插入真实ip,并标记为1。如果是多个,就执行多次插入语句
mysql> insert into executors(host,port,active) values('192.168.33.11',12331,1);

3.4 Executor端Server安装

执行端服务我们规划安装到node3(192.168.33.11)节点,我们首先把azkaban-exec-server-3.73.1.tar.gz包上传到node3。

3.4.1 解压

在Azkaban的执行节点,解压azkaban-exec-server-3.73.1.tar.gz包:

tar -zxf azkaban-exec-server-3.73.1.tar.gz

解压之后,目录说明如下:

Folder Description
bin 启动/停止Azkaban solo 服务的脚本
conf Azkaban solo 服务的配置文件
lib Azkaban的jar依赖库
extlib 添加到extlib 的其它jar将添加到Azkaban的 classpath中
plugins 可以安装插件的目录(需要安装插件时再创建)

3.4.2 配置azkaban.properties

进入到 azkaban-exec-server-3.73.1/conf/ 文件夹下,修改:

# Azkaban Personalization Settings
azkaban.name=My-Azkaban
azkaban.label=My Azkaban
# 十六进制值,默认为 #FF3601(红色)。允许您为Azkaban UI设置样式颜色
azkaban.color=#fc5b13
# Azkaban将显示的时区
default.timezone.id=Asia/Shanghai

azkaban.default.servlet.path=/index
# 设置ui的css和javascript文件的目录
web.resource.dir=web/
# Azkaban plugin settings
azkaban.jobtype.plugin.dir=plugins/jobtypes
# Directory where viewer plugins are installed.
viewer.plugin.dir=plugins/viewer
# Azkaban UserManager class
user.manager.class=azkaban.user.XmlUserManager
user.manager.xml.file=conf/azkaban-users.xml
# Loader for projects
executor.global.properties=conf/global.properties
azkaban.project.dir=projects

# Velocity dev mode
velocity.dev.mode=false
# Azkaban Jetty server properties.
jetty.use.ssl=false
jetty.maxThreads=25
jetty.port=8081
# ssl端口
#jetty.ssl.port=8443
# 密钥库文件。使用绝对路径。keytool -keystore keystore -alias jetty -genkey -keyalg RSA
#jetty.keystore=/app/disk1/keystore
# jetty密码(ssl文件密码)
#jetty.password=
# 密钥密码(jetty主密码与keystore文件相同)
#jetty.keypassword=
# The trust store(SSL文件名)
#jetty.truststore=
# The trust password(SSL文件密码)
#jetty.trustpassword=
jetty.connector.stats=true

# Azkaban Executor settings
# executo 端口,默认为12321。
executor.port=12331
executor.connector.stats=true
executor.maxThreads=50
executor.flow.threads=30
# 日志保留时间,默认为12周,这里配置为4周
execution.logs.retention.ms=2419200000
# Where the Azkaban web server is located
azkaban.webserver.url=http://192.168.33.9:8081
# mail settings
# azkaban用于发送电子邮件的地址
#[email protected]
# 电子邮件服务主机
#mail.host=smtp.xxx.com
# 电子邮件服务用户名
#mail.user=
# 电子邮件用户名密码
#mail.password=
job.failure.email=
job.success.email=
# User facing web server configurations used to construct the user facing server URLs. They are useful when there is a reverse proxy between Azkaban web servers and users.
# enduser -> myazkabanhost:443 -> proxy -> localhost:8081
# when this parameters set then these parameters are used to generate email links.
# if these parameters are not set then jetty.hostname, and jetty.port(if ssl configured jetty.ssl.port) are used.
# azkaban.webserver.external_hostname=myazkabanhost.com
# azkaban.webserver.external_ssl_port=443
# azkaban.webserver.external_port=8081

# JMX stats
# 每个作业可以请求的最大初始内存量。此验证在项目上载时执行
#job.max.Xms=1GB
# 每个作业可以请求的最大内存量。此验证在项目上载时执行
#job.max.Xmx=2GB
# 防止除具有Admin角色的人以外的任何人创建新项目
lockdown.create.projects=false
# 缓存目录
cache.directory=cache

# Azkaban mysql settings by default. Users should configure their own username and password.
database.type=mysql
mysql.port=3306
mysql.host=node1
mysql.database=airflow
mysql.user=root
mysql.password=123456
# Azkaban Web客户端可以打开到数据库的连接数
mysql.numconnections=100

3.4.3 发送到其他节点

# 可以node2和node3都作为执行端服务,例如这里只启一个执行服务,
#scp -r azkaban-exec-server-3.73.1 root@node2:/opt/
scp -r azkaban-exec-server-3.73.1 root@node3:/opt/

3.4.4 启动

注意:启动顺序一定是先启动azkaban-exec-server,再启动azkaban-web-server

cd /opt/azkaban-exec-server-3.73.1
bin/start-exec.sh

查看启动信息

# 查看日志。start-exec.sh启动时会生成一个 executorServerLog_* 开头的日志文件,可以查看启动信息
tail -f executorServerLog_*.out

# jps可以查看到 AzkabanExecutorServer进程
jps

# 查看执行端口状态,最好执行下面的请求。如果成功会提示:{"status":"success"}
curl -G "localhost:12331/executor?action=activate" && echo

3.4.5 关闭

如果需要重启集群或者关闭集群时,可以执行如下命令:

bin/shutdown-exec.sh

3.5 WEB端Server安装

web端服务我们规划在node1(192.168.33.9)节点,我们首先把azkaban-web-server-3.73.1.tar.gz包上传到node1。

3.5.1 解压

在Azkaban的web端节点,解压azkaban-web-server-3.73.1.tar.gz包:

tar -zxf azkaban-web-server-3.73.1.tar.gz

3.5.2 配置azkaban.properties

进入到 azkaban-web-server-3.73.1/conf 文件夹下,修改:

# Azkaban Personalization Settings
azkaban.name=My-Azkaban
azkaban.label=My Azkaban
# 十六进制值,默认为 #FF3601(红色)。允许您为Azkaban UI设置样式颜色
azkaban.color=#fc5b13
# Azkaban将显示的时区
default.timezone.id=Asia/Shanghai

azkaban.default.servlet.path=/index
# 设置ui的css和javascript文件的目录
web.resource.dir=web/
# Directory where viewer plugins are installed
viewer.plugin.dir=plugins/viewer
# Azkaban UserManager class
user.manager.class=azkaban.user.XmlUserManager
user.manager.xml.file=conf/azkaban-users.xml
# Loader for projects
executor.global.properties=conf/global.properties
azkaban.project.dir=projects

# Velocity dev mode
velocity.dev.mode=false
# Azkaban Jetty server properties.
jetty.use.ssl=false
jetty.maxThreads=25
jetty.port=8081
# ssl端口
#jetty.ssl.port=8443
# 密钥库文件。使用绝对路径。keytool -keystore keystore -alias jetty -genkey -keyalg RSA
#jetty.keystore=/app/disk1/keystore
# jetty密码(ssl文件密码)
#jetty.password=
# 密钥密码(jetty主密码与keystore文件相同)
#jetty.keypassword=
# The trust store(SSL文件名)
#jetty.truststore=
# The trust password(SSL文件密码)
#jetty.trustpassword=
jetty.connector.stats=true

# Azkaban Executor settings
executor.port=12331
executor.host=ip/hostname
executor.connector.stats=true
# mail settings
# azkaban用于发送电子邮件的地址
#[email protected]
# 电子邮件服务主机
#mail.host=smtp.xxx.com
# 电子邮件服务用户名
#mail.user=
# 电子邮件用户名密码
#mail.password=
job.failure.email=
job.success.email=
# User facing web server configurations used to construct the user facing server URLs. They are useful when there is a reverse proxy between Azkaban web servers and users.
# enduser -> myazkabanhost:443 -> proxy -> localhost:8081
# when this parameters set then these parameters are used to generate email links.
# if these parameters are not set then jetty.hostname, and jetty.port(if ssl configured jetty.ssl.port) are used.
# azkaban.webserver.external_hostname=myazkabanhost.com
# azkaban.webserver.external_ssl_port=443
# azkaban.webserver.external_port=8081

# JMX stats
# 每个作业可以请求的最大初始内存量。此验证在项目上载时执行
#job.max.Xms=1GB
# 每个作业可以请求的最大内存量。此验证在项目上载时执行
#job.max.Xmx=2GB
# 缓存目录
cache.directory=cache
#Project Manager Settings
# 上载项目时使用的临时目录
project.temp.dir=temp
# 清理前保留的未使用项目版本数
project.version.retention=3
# 自动将项目的创建者作为代理用户添加到项目中
creator.default.proxy=true
# 防止除具有Admin角色的人以外的任何人创建新项目
lockdown.create.projects=false
# 防止除管理员用户和具有上传项目权限的用户以外的任何人
lockdown.upload.projects=false
# 会话时间以毫秒为单位
session.time.to.live=86400000
# 被驱逐前的最大会话数
max.num.sessions=10000

# Azkaban mysql settings by default. Users should configure their own username and password.
database.type=mysql
mysql.port=3306
mysql.host=node1
mysql.database=airflow
mysql.user=root
mysql.password=123456
# Azkaban Web客户端可以打开到数据库的连接数
mysql.numconnections=100

#Multiple Executor
# azkaban在多执行器模式下运行设置为true
azkaban.use.multiple.executors=true
# 调度时使用的常见硬分隔符列表。要从StaticRemaining,FlowSize,MinimumFreeMemory和CpuStatus中选择。过滤顺序无关紧要
azkaban.executorselector.filters=StaticRemainingFlowSize,MinimumFreeMemory,CpuStatus
# 用于对给定流的可用执行程序进行排名的整数权重。目前,{ComparatorName}可以是NumberOfAssignedFlowComparator,Memory,LastDispatched和CpuUsage作为ComparatorName。
# 例如: - azkaban.executorselec tor.comparator.Memory = 2
azkaban.executorselector.comparator.Memory=1
azkaban.executorselector.comparator.NumberOfAssignedFlowComparator=1
azkaban.executorselector.comparator.LastDispatched=1
azkaban.executorselector.comparator.CpuUsage=1
# 应该从Web服务器初始化启用队列处理器
azkaban.queueprocessing.enabled=true
# 可以在Web服务器上排队的最大流量
azkaban.webserver.queue.size=100000
# 无执行程序统计信息刷新时可以处理的最长时间(以毫秒为单位)	
azkaban.activeexecutor.refresh.milisecinterval=50000
# 在没有执行程序统计信息刷新的情况下可以处理的最大排队流数
azkaban.activeexecutor.refresh.flowinterval=5
# 刷新执行程序统计信息的最大线程数
azkaban.executorinfo.refresh.maxThreads=5

3.5.3 配置 azkaban-users.xml

permissions 说明
ADMIN 授予Azkaban所有物品的所有权限。
READ 为用户提供对每个项目及其日志的只读访问权限
WRITE 允许用户上传文件,更改作业属性或删除任何项目
EXECUTE 允许用户触发任何流的执行
SCHEDULE 用户可以为任何流添加或删除计划
CREATEPROJECTS 如果项目创建被锁定,则允许用户创建新项目

编辑azkaban-web-server-3.73.1/conf/azkaban-users.xml,配置自己的用户信息

<azkaban-users>
  <user username="azkaban" password="azkaban" groups="admin"  />
  <user username="yore" password="yore" groups="admin" />
  <user username="user1" password="user1***" groups="mydepart" />
  <user username="user2" password="user2***" groups="mydepart" />
  <user username="metrics" password="metrics" roles="metrics" />

  <group name="admin" roles="admin" />
  <group name="mydepart" roles="mydepart" />

  <!-- role:ADMIN、READ、WRITE、EXECUTE、SCHEDULE、CREATEPROJECTS -->
  <role name="admin" permissions="ADMIN"/>
  <role name="mydepart" permissions="READ,WRITE,EXECUTE"/>
  <role name="metrics" permissions="METRICS"/>
  
</azkaban-users>

3.5.4 启动

注意:启动顺序一定是先启动azkaban-exec-server,再启动azkaban-web-server

cd azkaban-web-server-3.73.1
bin/start-web.sh

查看启动信息

# 查看日志。start-exec.sh启动时会生成一个 webServerLog_* 开头的日志文件,可以查看启动信息
# 可能会看到这个错误信息: ERROR [PluginCheckerAndActionsLoader] [Azkaban] plugin path plugins/triggers doesn't exist! 
# 这个信息可以不用处理,服务是可以正常使用的
tail -f webServerLog_*.out

# jps可以查看到 AzkabanWebServer 进程
jps

3.5.5 关闭

如果需要重启集群或者关闭集群时,可以执行如下命令:

bin/shutdown-web.sh 

3.5.6 访问

浏览器访问https://node1:8081/

  • ADMIN权限的用户: username=azkaban password=azkaban
    或者 username=yore password=yore
  • METRICS权限用户: username=odps password=odps

登陆后界面如下
Azkaban Web UI
首页可看到有六个菜单:

  • Projects : 可以创建工程,所有的flow将在工程中运行
  • Scheduling : 显示定时任务
  • Executing : 显示当前运行的任务
  • History : 显示历史运行任务
  • Flow Trigger Schedule : 流触发时间表
  • Documentation : 文档



4 使用

4.1 测试项目

创建一个简单的定时调度任务,查看Azkaban是否可以正常执行,且可以在执行节点执行任务

4.1.1 Project创建

一个工程可以包含一个或多个flows,一个flow包含多个job。Job是我们想在Azkaban中运行的一个进程,可以是简单的Linux命令,可以是Java程序,也可以是复杂的shell脚本,如果我们安装了插件,也可以运行插件。一个Job可以依赖于另一个Job,这种多个Job和他们的依赖组成的图表叫做Flow。

创建工程:

  • 点击绿色的按钮+ Create Project,输入Project的名字说明,点击 蓝色的 Create Project。例如这里创建一个 exec-test 项目。
  • 会进入到创建的Project详细页面
    • Flows 工作流程,由多个Job组成
    • Permissions 权限管理
    • Project Logs 工作日志
4.1.2 Job创建

创建一个以.job结尾的文本文件,例如创建一个用来打印执行端hostname的Job,名字叫做 hostname.job。输入如下内容,type=command表示使用的是Unix原生命令执行:

#hello-world.job
type=command
command=hostname

将上面的文件打包为zip,然后通过Azkaban Web Client页面上传压缩包。
Upload -> 选择文件 -> Upload

Execute Flow
Execute Flow hostname
Schedule: 执行的方式,默认为每分钟执行一次
Schedule Flow Option
Execute: 开始执行

4.1.3 查看Job执行

History -> 选择一个执行过的Job的Execution Id -> Job List -> Log

可以在日志中查看到打印的内容,可以看到Job执行状态为Finishing job hostname at 1559010079981 with status SUCCEEDED,同时可以看到执行的命令为:Command: hostname,执行的结果28-05-2019 10:21:19 CST hostname INFO - node3,说明任务确实分发到node3上定时调度并成功执行了。

azkaban job log

4.1.4 停止Job

如果某个Job不需要定时执行了,可以在页面点击 Scheduling -> 选择需要取消的Job -> 点击红色按钮Remove Schedule ,这样就取消某个Job的调度任务。


4.2 Conditionsl Workflow


5 脚本的远程调度方案

Azkaban支持多个执行服务端,当我们提交一个定时任务,当不会因为某个节点有问题而无法正常执行任务的情况,从而保证高可用,如下图,是两个Azkaban执行服务端处于激活状态。但我们在执行调度任务时,往往还有会有一些限制,比如现在我们提交的某个任务只能在node3节点执行,应为之后node3节点上安装了我们脚本用的服务,这时就需要指定执行节点,最简单的就是将node2节点的元数据的激活状态手动改为0,但是这样就失去了高可用的优势。
在这里插入图片描述
例如在前面我们提交了一个hostname 的定时调度任务,在提交后查看执行的日志发现其在node3节点执行(4.1.3 查看Job执行),当我们取消定时任务调度后再次提交很有可能任务就提交到node2上执行了,也可以修改元数据的executors表的node3的active状态为0,再次提交任务就会在node2上执行。

5.1 通过Azkaban指定

为了让某个定时任务在我们指定的执行节点上执行,在提交定时任务时,需要我们进行如下设置(如下图):点击 Flow Parameters -> Add Row ,然后在Name列填写useExecutor,Value列填写3(这个值就是上图executors表的node3对应的id),然后填写调度正则规则,再次执行即可。
在这里插入图片描述

5.2 通过脚本指定

Expect 是用于自动化交互式应用程序(例如telnet,ftp,passwd,fsck,rlogin,tip等)的工具。Expect确实使这些事情变得微不足道。Expect对于测试这些相同的应用程序也很有用。通过添加Tk,我们还可以在X11 GUI中包装交互式应用程序。xpect可以使其它难以完成的各种任务变得容易。您会发现Expect是绝对有价值的工具-使用它,我们可以通过它自动化我们从未想过的任务,而且将能够使其快速,轻松地实现自动化。

Expect是在1987年9月构想的。版本2的大部分是在1990年1月至1990年4月之间设计和编写的。此后进行了较小的演变,直到Tcl 6.0发布。那时(1991年10月)。版本3重写了Expect的大约一半,有关更多信息请参见 HISTORY文件,HISTORY文件包含在Expect分发包中。1993年1月左右,推出了Expect 4的Alpha版本,这包括Tk支持以及大量增强功能,对用户界面本身进行了一些更改,这就是更改主要版本号的原因。1993年8月发布了Expect 4的生产版本。1993年10月,发布了Expect 5的Alpha版本以匹配Tcl 7.0,这个版本进行了大量增强,包括对用户界面本身进行了一些更改,这就是(再次)更改主版本号的原因。94年3月发布了Expect 5的生产版本。在1999年夏天,官方为了支持Tcl 8.2,对Expect进行了大量重写(Expect从未移植到8.1,因为它包含基本缺陷),这包括创建exp通道驱动程序和对象支持,以便利用新的regexp引擎和UTF/Unicode,用户界面高度兼容,但并不完全向后兼容。

5.2.1 安装方式一:yum

这种方式是比较简单的,如果可以访问网络,直接yun安装即可。

# yum安装
yum  install -y expect

# 检查
expect -v

5.2.2 安装方式二:从源码编译安装

就如简介中介绍的 expect 需要 tcl 的支持。因此安装之前需要先安装tcl。TCL的下载页面可访问 download.html,TCL的编译指南 compile.html。仅需在调度服务节点安装就行,不需要在脚本的执行端安装,例如在node3安装上expect,后期如果要在其它远程服务上执行脚本,可以通过Azkaban指定在node3上开启定时调度即可。tcl的过程如下。

# 1 下载 
wget https://prdownloads.sourceforge.net/tcl/tcl8.6.9-src.tar.gz

# 2 解压
tar -zxf tcl8.6.9-src.tar.gz
cd tcl8.6.9

# 3 目录结构如下。可以看到这是一个包含多系统的源码包
 [root@cdh5 tcl8.6.9]# tree -L 1 ./
 ./
 ├── ChangeLog
 ├── ChangeLog.1999
 ├── ChangeLog.2000
 ├── ChangeLog.2001
 ├── ChangeLog.2002
 ├── ChangeLog.2003
 ├── ChangeLog.2004
 ├── ChangeLog.2005
 ├── ChangeLog.2007
 ├── ChangeLog.2008
 ├── changes
 ├── compat
 ├── doc
 ├── generic
 ├── library
 ├── libtommath
 ├── license.terms
 ├── macosx
 ├── pkgs
 ├── README
 ├── tests
 ├── tools
 ├── unix
 └── win

# 4 进入unix。本次以Linux为例
cd unix

# 5 编译
# 可以指定参数,
#  --prefix=directory  默认是在 /usr/local 下
./configure
make
make test
make install

安装 expect,Expect下载页面可访问sourceforge page。安装过程如下。

# 1 下载
wget https://jaist.dl.sourceforge.net/project/expect/Expect/5.45.4/expect5.45.4.tar.gz

# 2 解压
tar -zxf expect5.45.4.tar.gz

# 3 进入到expect
 cd expect5.45.4
 
# 4 编译安装
./configure && make && make install

# 5 检查
expect -v

5.2.3 以shell脚本形式使用

例如要在某台机器(暂时就叫它mars节点吧)上执行一个expect_demo.sh脚本(这个脚本也许会执行一些神秘的代码,虽然我目前还不知道,但可以期待),例如这个脚本在mars机器的/home/mars下,并且我们知道一个通往那里的用户名(mars)和密码(***Hello Mars***)。完整脚本如下所示,保存为job.sh脚本文件,同时赋予它执行的权限,并将其方在node3节点的/app/schedule下。

#!/bin/bash

# 匹配提示符
CMD_PROMPT="\](\$|#)"

# 要执行的脚本
script="/home/mars/expect_demo.sh"

# 定义访问mars的基本信息,包括用户名、密码、主机名、端口
username="mars"
password="***Hello Mars***"
host="mars"
port=22

# expect执行的主体代码
expect -c "
    send_user connecting\ to\ $host...\r
    spawn ssh -p $port $username@$host
    expect {
        *yes/no { send -- yes\r;exp_continue;}
        *password* { send -- $password\r;}
    }
    expect -re $CMD_PROMPT
    send -- $script\r
    expect -re $CMD_PROMPT
    exit
"

echo -e "\n************************************************************************************"
echo " 		 Successful execution at node ${host}	"
echo -e "************************************************************************************\n"

# send_user		空格要转义.  是回显,相当于echo。
# send			发指令到对端,向进程发送输入内容。
# exp_continue	重新匹配所在的expect,相当于while的continue,表示expect的匹配从头开始继续匹配。
# spawn			开启新的进程
# expect		匹配上一条指令的输出
# -re			表示匹配正则表达式

# exit,close,wait:exit表示退出脚本,close表示立即关闭过程,而wait则是等待过程返回eof时关闭。
# ineract       留在环境中不退出 
# interact:    运行表示将控制权交给用户,与spawn生成的进程进行交互。由用户与spawn生成的进程进行交互,比如登录ftp服务器并下载的过程中,
# #             登录ftp服务器的过程可以由用户输入自己的用户名和密码,然后用户再输入q字符将控制权交给脚本,由脚本完成后面的交互动作。

接下来编写Azkaban调度脚本文件mars.job,内容如下,编写完毕后,将其打包为zip包,按照 4 使用 节提交到Azkaban上,并设置自己的调度规则。最后执行,但因为这个神秘的任务必须要在node3上才能正常执行,所以需要指定node3作为Azkaban的执行节点,这样我们就成功完成了这个神秘的Job任务。

type=command
command=sh /app/schedule/job.sh

5.2.4 以expect脚本形式使用

如果觉得shell看着有点土,当然也可以直接以expect脚本形式执行。在这个脚本中同样要到mars机器上去按照给定的执行规则(也许是1分钟去执行一次、也许要要几年去执行一次)去执行一个 /home/mars/expect_demo.sh 脚本,整脚本如下所示,保存为 job.exp 脚本文件(同样要给它执行的权限),并将其方在node3节点的 /app/schedule 下。

#!/usr/local/bin/expect

# 要执行的脚本  
set script "/home/mars/expect_demo.sh "

# 定义访问mars的基本信息,包括用户名、密码、主机名、端口
set username "mars"
set password "***Hello Mars***"
set host "mars"
set port "22"

spawn ssh -p $port $username@$host
expect {
"*yes/no" {send "yes\r"; exp_continue} 
"*password:" {send "$password\r"}
"*Password:" {send "$password\r"}
}
puts "\n************************************************************************************"
puts "\n		 LOGIN ${host} SUCCESS  START TO EXCE COMMAND	"
puts "\n************************************************************************************"

expect "$username@*"  {send "sh $script\r"}
expect "$username@*"  {send "exit\r"}

#exit
expect eof

和使用shell脚本一样,需要编写一个Azkaban调度脚本文件mars.job,内容如下,编写完毕后按照前面说的方式执行即可。

type=command
command=expect /app/schedule/job.exp

5.3 通过Ansible

详见我的另一篇 blog Ansible Quickstart



发布了40 篇原创文章 · 获赞 97 · 访问量 15万+

猜你喜欢

转载自blog.csdn.net/github_39577257/article/details/99970514
今日推荐