Azkaban是由Linkedin公司推出的⼀个批量⼯作流任务调度器,主要⽤于在⼀个⼯作流内以⼀个特定的顺序运⾏⼀组⼯作和流程,它的配置是通过简单的key:value对的⽅式,通过配置中的dependencies 来设置依赖关系,这个依赖关系必须是⽆环的,否则会被视为⽆效的⼯作流。Azkaban使⽤job配置⽂件建⽴任务之间的依赖关系,并提供⼀个易于使⽤的web⽤户界⾯维护和跟踪你的⼯作流。azkaban的设计⾸先考虑了可⽤性。它已经在LinkedIn上运⾏了⼏年,并驱动了许多Hadoop和数据仓库流程。
知名度⽐较⾼的应该是Apache Oozie,但是其配置⼯作流的过程是编写⼤量的XML配置,⽽且代码复杂度⽐较⾼,不易于⼆次开发。另外⼀个应⽤也⽐较⼴泛的调度系统是Airflow,但是其开发语⾔是Python。
选择Azkaban的理由:
实际项⽬中经常有这些场景:每天有⼀个⼤任务,这个⼤任务可以分成A,B,C,D四个⼩任务,A,B任务之间没有依赖关系,C任务依赖A,B任务的结果,D任务依赖C任务的结果。⼀般的做法是,开两个终端同时执⾏A,B,两个都执⾏完了再执⾏C,最后再执⾏D。这样的话,整个的执⾏过程都需要⼈⼯参加,并且得盯着各任务的进度。但是我们的很多任务都是在深更半夜执⾏的,通过写脚本设置crontab执⾏。其实,整个过程类似于⼀个有向⽆环图(DAG)。每个⼦任务相当于⼤任务中的⼀个流,任务的起点可以从没有度的节点开始执⾏,任何没有通路的节点之间可以同时执⾏,⽐如上述的A,B。总结起来的话,我们需要的就是⼀个⼯作流的调度器,⽽Azkaban就是能解决上述问题的⼀个调度器。
参考:https://azkaban.github.io/azkaban/docs/latest/
Azkaban在LinkedIn上实施,以解决Hadoop作业依赖问题。我们有⼯作需要按顺序运⾏,从ETL⼯作到数据分析产品。最初是单⼀服务器解决⽅案,随着多年来Hadoop⽤户数量的增加,Azkaban 已经发展成为⼀个更强⼤的解决⽅案。Azkaban总共有三个⻆⾊:关系型数据库(MySQL)、AzkabanWebServer、AzkabanExecutorServer。Azkaban使⽤MySQL存储服务状态,AzkabanWebServer和AzkabanExecutorServer都需要访问MySQL的DB数据库
AzkabanWebServer是所有Azkaban的主要管理器。它处理项⽬管理,身份验证,调度程序和执⾏监视。它还⽤作Web⽤户界⾯。 使⽤Azkaban很容易。 Azkaban使⽤* .job键值属性⽂件来定义⼯作流程中的各个任务,并使⽤dependencies 属性来定义作业的依赖关系链。这些作业⽂件和相关的代码可以存档为*.zip,并通过Azkaban UI或curl通过Web服务器上传。
以前的Azkaban版本(version 3.0之前)在单个服务器中同时具有AzkabanWebServer和
AzkabanExecutorServer功能。此后,执⾏程序已被分离到单独的服务器中。拆分这些服务的原因有很多:⽅便的扩展Executor的数量,并在失败的情况下可以恢复。分离以后在对Azkaban升级的时候对⽤户的使⽤影响很⼩。
[root@CentOS ~]# yum install git
[root@CentOS ~]# git clone https://github.com/azkaban/azkaban.git
[root@CentOS ~]# cd azkaban/
[root@CentOS azkaban]# ./gradlew build installDist
...漫⻓的等待...
Starting a Gradle Daemon, 1 incompatible and 1 stopped Daemons could not be reused,
use --status for details
Parallel execution with configuration on demand is an incubating feature.
> Task :azkaban-web-server:npm_install
added 39 packages in 0.901s
> Task :azkaban-web-server:jsTest
addClass
✓ should add class into element
✓ should not add a class which already exists in element
CronTransformation
✓ should transfer correctly
ValidateQuartzStr
✓ validate Quartz String corretly
momentJSTest
✓ momentJSTest
✓ momentTimezoneTest
6 passing (11ms)
BUILD SUCCESSFUL in 9s
114 actionable tasks: 8 executed, 106 up-to-date
在version 3.0中我们提供了三种模式:独⽴的"solo-server"模式、较重的"two server"模式以及"multipleexecutor"模式。其中solo server mode 使⽤的内嵌的H2 DB,所有的web server和executor server运⾏在⼀个相同的进程中,该种模式适合测试或者任务调度规模⽐较⼩;two server mode⽤于⽣产环境,后台的DB数据库使⽤MySQL,其中Webserver和executorserver应该被部署在不同的主机上;multipleexecutor mode 也通常⽤于⽣产环境,后台的DB数据库使⽤MySQL,其中Webserver和executorservers应该被部署在不同的主机上;
azkaban-solo-server-*.tar.gz
,将该安装解压到/usr
⽬录下[root@CentOS azkaban]# tree azkaban-solo-server/build/distributions
azkaban-solo-server/build/distributions
!"" azkaban-solo-server-3.81.0-1-g304593d.tar.gz
#"" azkaban-solo-server-3.81.0-1-g304593d.zip
[root@CentOS azkaban]# tar -zxf azkaban-solo-server/build/distributions/azkaban-soloserver-3.81.0-1-g304593d.tar.gz -C /usr/
[root@CentOS azkaban]# cd /usr/
[root@CentOS usr]# mv azkaban-solo-server-3.81.0-1-g304593d azkaban-solo-server
[root@CentOS azkaban-solo-server]# ls -l
总⽤量 24
drwxr-xr-x. 3 root root 4096 12⽉ 17 16:11 bin #启动脚本
drwxr-xr-x. 2 root root 4096 12⽉ 17 16:11 conf #配置⽬录
drwxr-xr-x. 2 root root 4096 12⽉ 17 16:11 lib #运⾏所需依赖jar
drwxr-xr-x. 3 root root 4096 12⽉ 17 16:11 plugins #插件安装⽬录
drwxr-xr-x. 2 root root 4096 12⽉ 17 16:11 sql #sql脚本
drwxr-xr-x. 6 root root 4096 12⽉ 17 16:11 web #web服务相关
[root@CentOS azkaban-solo-server]# tree conf/
conf/
!"" azkaban.properties
!"" azkaban-users.xml
#"" global.properties
0 directories, 3 files
[root@CentOS azkaban-solo-server]# tree plugins/
plugins/
#"" jobtypes
#"" commonprivate.properties
1 directory, 1 file
2.修改 azkaban.properties
配置⽂件
default.timezone.id=Asia/Shanghai #修改时区
jetty.port=8082 #配置azkabanweb服务器地址
3.修改commonprivate.properties
配置⽂件
memCheck.enabled=false #关闭执⾏节点内存检查,默认如果执⾏节点内存⼩于6GB,不会提交任务
4.运⾏Solo Server服务器,访问 CentOS:8082
[root@CentOS azkaban-solo-server]# ./bin/start-solo.sh #启动
[root@CentOS azkaban-solo-server]# jps
5638 AzkabanSingleServer
5679 Jps
5.关闭azkaban服务
[root@CentOS azkaban-solo-server]# ./bin/shutdown-solo.sh
Killing solo-server. [pid: 18912], attempt: 1
shutdown succeeded
mysql> create database azkaban;
Query OK, 1 row affected (0.00 sec)
mysql> show create database azkaban;
+----------+--------------------------------------------------------------------+
| Database | Create Database |
+----------+--------------------------------------------------------------------+
| azkaban | CREATE DATABASE `azkaban` /*!40100 DEFAULT CHARACTER SET latin1 */ |
+----------+--------------------------------------------------------------------+ 1 row in set (0.00 sec)
mysql> use azkaban;
Database changed
mysql> source /root/create-all-sql-3.81.0-1-g304593d.sql
Query OK, 0 rows affected (0.00 sec)
...
Query OK, 0 rows affected (0.00 sec)
mysql> show tables;
+-----------------------------+
| Tables_in_azkaban |
+-----------------------------+
| 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 |
| ramp |
| ramp_dependency |
| ramp_exceptional_flow_items |
| ramp_exceptional_job_items |
| ramp_items |
| triggers |
+-----------------------------+
34 rows in set (0.00 sec)
mysql>
[root@CentOSX ~]#tar -zxf azkaban-exec-server-3.81.0-1-g304593d.tar.gz -C /usr/
[root@CentOSX ~]# mv /usr/azkaban-exec-server-3.81.0-1-g304593d/ /usr/azkabanexec-server
2.配置azkaban.properties
default.timezone.id=Asia/Shanghai
jetty.port=8082
azkaban.webserver.url=http://CentOSA:8082
database.type=mysql
mysql.port=3306
mysql.host=CentOSB
mysql.database=azkaban
mysql.user=root
mysql.password=root
mysql.numconnections=100
3.配置commonprivate.properties
memCheck.enabled=false
4.启动azkaban执⾏服务器
[root@CentOSX azkaban-exec-server]# ./bin/start-exec.sh
[root@CentOSX azkaban-exec-server]# jps
82312 AzkabanExecutorServer
82335 Jps
5.激活azkaban执⾏服务器(每次重启,都需要激活)
[root@CentOSX azkaban-exec-server]# curl -G
"localhost:$(<./executor.port)/executor?action=activate" && echo
{"status":"success"}
[root@CentOSA ~]# tar -zxf azkaban-web-server-3.81.0-1-g304593d.tar.gz -C /usr/
[root@CentOSA ~]# mv /usr/azkaban-web-server-3.81.0-1-g304593d/ /usr/azkaban-webserver/
2.配置azkaban.properties
default.timezone.id=Asia/Shanghai
jetty.port=8082
mysql.port=3306
mysql.host=CentOSB
mysql.database=azkaban
mysql.user=root
mysql.password=root
mysql.numconnections=100
#azkaban.executorselector.filters=StaticRemainingFlowSize,MinimumFreeMemory,CpuSta
tus
azkaban.executorselector.filters=StaticRemainingFlowSize,CpuStatus #关闭对执⾏服务器
内存检查-测试环境
3.启动web服务器
[root@CentOSA azkaban-web-server]# jps
82565 AzkabanWebServer
82312 AzkabanExecutorServer
82590 Jps
4.访问azkaban服务: http://centosa:8082/index
Flow1.0
type=command
command=echo 'Hello Azkaban!'
将以上⽂件打包成zip包然后上传!
Flow 2.0
1.创建xxx.project⽂件
azkaban-flow-version: 2.0
2.创建⼀个xxx.flow
nodes:
- name: jobA
type: command
config:
command: echo "This is an echoed text."
nodes:
- name: jobA
type: command
config:
command: sh ./demo02/bin/showpath.sh
current_path=$(pwd)
echo ===============current_path==============
echo $current_path
echo ===============tree==============
tree $current_path
将xxx.project、demo02.flow、bin/showpath.sh放置在demo02⽬录结构下
!"" demo02
!"" bin
$ #"" showpath.sh
!"" demo02.flow
#"" flow20.project
nodes:
- name: jobA
type: javaprocess
config:
classpath: ./demo03/libs/*
java.class: com.baizhi.SpringBootApplication
package com.baizhi;
public class SpringBootApplication {
public static void main(String[] args) {
System.out.println("this is java code");
}
}
使⽤maven打包
!"" demo03
!"" libs
$ #"" azkaban-1.0-SNAPSHOT.jar
!"" demo03.flow
!"" flow20.project
nodes:
- name: jobA
type: javaprocess
config:
classpath: ./demo04/libs/"*"
java.class: com.baizhi.SpringBootApplication
- name: jobB
type: command
config:
command: sh ./demo04/bin/showpath.sh
!"" demo04
!"" bin
$ #"" showpath.sh
!"" demo04.flow
!"" flow20.project
#"" libs
#"" azkaban-1.0-SNAPSHOT.jar
nodes:
- name: job01
type: noop
dependsOn:
- job02
- job03
- name: job02
type: javaprocess
config:
classpath: ./demo05/libs/"*"
java.class: com.baizhi.SpringBootApplication
- name: job03
type: command
config:
command: sh ./demo05/bin/showpath.sh
- name: job04
type: command
dependsOn:
- job01
config:
command: echo '==============end01============='
command.1: echo '============end02============='
command.2: echo '============end03============='
nodes:
- name: job01
type: noop
dependsOn:
- job02
- job03
- name: job02
type: flow
nodes:
- name: job02_1
type: command
config:
command: echo '==============job02_1============='
- name: job02_2
type: command
config:
command: echo '==============job02_1============='
- name: job02_3
type: command
dependsOn:
- job02_1
- job02_2
config:
command: echo '==============job02_3============='
- name: job03
type: command
config:
command: echo '==============job03============='
- name: job04
type: command
dependsOn:
- job01
config:
command: echo '==============end01============='
command.1: echo '============end02============='
command.2: echo '============end03============='
---
config:
user.to.proxy: root
failure.emails: 1152926811@qq.com,784010850@qq.com
success.emails: 1152926811@qq.com,784010850@qq.com
notify.emails: 1152926811@qq.com,784010850@qq.com
nodes:
- name: job01
type: command
config:
command: sh ./demo08/bin/hdfs.sh
notify.emails:表示成功或者失败都要给xxx邮件
为了能够使⽤邮件功能,需要⽤户配置exec-server/web-server添加以下配置
# email 相关配置
mail.sender=1152926811@qq.com
mail.host=smtp.qq.com
mail.user=1152926811@qq.com
mail.password=邮箱的授权码|密码
# 任务调度成功&失败的发送邮箱
job.failure.email=1152926811@qq.com
job.success.email=1152926811@qq.com