目录
1 概述
1.1 什么是Azkaban
Azkaban是由Linkedin公司推出的一个批量工作流任务调度器,主要用于在一个工作流内以一个特定的顺序运行一组工作和流程,它的配置是通过简单的key:value对的方式,通过配置中的Dependencies 来设置依赖关系。Azkaban使用job配置文件建立任务之间的依赖关系,并提供一个易于使用的web用户界面维护和跟踪你的工作流。
1.2 Azkaban特点
- 兼容任何版本的hadoop
- 易于使用的Web用户界面
- 简单的工作流的上传
- 方便设置任务之间的关系
- 调度工作流
- 能够杀死并重新启动工作流
- 有关失败和成功的电子邮件提醒
1.3 常见工作流调度系统
- 1)简单的任务调度:直接使用crontab实现;
- 2)复杂的任务调度:开发调度平台或使用现成的开源调度系统,比如ooize、azkaban、Airflow、DophineSheduler等
1.4 Azkaban的架构
Azkaban由三个关键组件构成:
- AzkabanWebServer:AzkabanWebServer是整个Azkaban工作流系统的主要管理者,它用户登录认证、负责project管理、定时执行工作流、跟踪工作流执行进度等一系列任务。
- AzkabanExecutorServer:负责具体的工作流的提交、执行,它们通过mysql数据库来协调任务的执行。
- 关系型数据库(MySQL):存储大部分执行流状态,AzkabanWebServer和AzkabanExecutorServer都需要访问数据库。
1.5 Azkaban下载地址
下载地址:http://azkaban.github.io/downloads.html
2 Azkaban的操作使用
Azkaban Flow包括1.0和2.0.
简单的使用1.0即可,可以直接上手操作。对于复杂的一些嵌套流或需要流程控制的时候使用Flow2.0
2.1 多job配置
以埋点为例
FLOW1.0的写法:编写job文件
第一个job:hdfs_to_ods_event_log.job
#hdfs_to_ods_event_log.job
type=command
command=sh hdfs_to_ods_event_log.sh ${dt}
retries: 3
retry.backoff: 10000
第一个并行job:mysql_to_hive_sjzt_sys_code_detail.job
#mysql_to_hive_sjzt_sys_code_detail.job
type=command
command=sh mysql_to_hive_sjzt_sys_code_detail.sh
retries: 3
retry.backoff: 10000
第二个job:dwd_event_base_log.job依赖hdfs_to_ods_event_log.job和mysql_to_hive_sjzt_sys_code_detail.ob
#dwd_event_base_log.job
type=command
dependencies=hdfs_to_ods_event_log,mysql_to_hive_sjzt_sys_code_detail
command=sh dwd_event_base_log.sh ${dt}
retries: 3
retry.backoff: 10000
将job文件和需要执行的脚本文件等一起打包,注意必须是.zip文件,否则不能识别。如果在windows编写脚本及job文件需要转换unix风格文件,否则不能识别此文件。
第一步点击创建project按钮
第二步:创建任务名称
第三步:上传zip文件
第四步:点击Execute Flow。可以看到任务转换的流程图
第五步:设置参数并执行
第六步:点击joblist查看执行情况
可以看到任务执行成功status为succes状态。
FLOW2.0的写法:编写flow文件
第一步:声明使用的是flow2.0.编写azkaban.project文件
azkaban-flow-version: 2.0
注意:2.0与冒号之间有个空格否则不会识别
第二步:编写flow文件
nodes:
- name: hdfs_to_ods_event_log
type: command
config:
command: sh hdfs_to_ods_event_log.sh ${dt}
retries: 3
retry.backoff: 3000
- name: mysql_to_hive
type: command
config:
command: sh mysql_to_hive.sh ${dt}
retries: 3
retry.backoff: 3000
- name: dwd_event_base_log_table
type: sh dwd_event_base_log_table.sh ${dt}
dependsOn:
- hdfs_to_ods_event_log
- mysql_to_hive
config:
command: sh dwd_event_base_log_table.sh ${dt}
retries: 3
retry.backoff: 3000
注意点:
- 同一层级的对齐,不同层级的空格表示,不能是tab,只能是空格
- 冒号后有一个空格。
第三步:将azkaban.project文件.flow文件和脚本文件打成zip包上传到azkaban服务器,剩下的操作和前面flow1.0一致。
此处推荐使用flow1.0不容易出错。
2.2 自动重试案例【针对网络故障,可以自恢复】
关键配置:
参数说明:
- retries:重试次数
- retry.backoff:重试的时间间隔
2.3 手动重试
在界面上将不需要的任务disable掉,然后再执行即可
Enable 和 Disable 下面都分别有如下参数:
- Parents:该作业的上一个任务
- Ancestors:该作业前的所有任务
- Children:该作业后的一个任务
- Descendents:该作业后的所有任务
- Enable All:所有的任务
2.4 定时任务
第一步:点击schedule
第二步:设置具体需要执行的时间,和crontab设置一样,都是EL表达式
注意点:时区问题一定是Asia/Shanghai.如果不是修改executor服务器和web服务器配置
然后重启服务器,先启动executor服务器再启动web服务器,注意启动的时候是在bin目录的上一级。如下:
- sh bin/shutdown-web.sh
- sh bin/start-web.sh
2.5 邮件报警
第一步:azkaban web服务器conf目录下添加配置如下
mail.sender=dandan@xxx.com
mail.host=smtp-nw.xxx.com
mail.user=dandan@xxx.com
mail.password=xxx@xxxx
配置完后重启web服务器。邮件配置前提是邮箱开通了SMTP服务。
第二步:添加需要任务失败或成功需要接收邮件的人
2.6 条件工作流
条件工作流功能允许用户自定义执行条件来决定是否运行某些Job。条件可以由当前Job 的父 Job 输出的运行时参数构成,也可以使用预定义宏。在这些条件下,用户可以在确定 Job 执行逻辑时获得更大的灵活性,例如,只要父 Job 之一成功,就可以运行当前 Job。
1 基本原理
(1)父 Job 将参数写入 JOB_OUTPUT_PROP_FILE 环境变量所指向的文件
(2)子 Job 使用 ${jobName:param}来获取父Job 输出的参数并定义执行条件
2 支持的条件运算符:
(1)== 等于
(2)!= 不等于
(3)> 大于
(4)>= 大于等于
(5)< 小于
(6)<= 小于等于
(7)&& 与
(8)|| 或
(9)! 非
3 案例
需求:
JobA 执行一个 shell 脚本。
JobB 执行一个 shell 脚本,但 JobB 不需要每天都执行,而只需要每个周一执行。
(1)新建 JobA.sh
#!/bin/bash
echo "do JobA"
wk=`date +%w`
echo "{\"wk\":$wk}" > $JOB_OUTPUT_PROP_FILE
(2)新建 JobB.sh
#!/bin/bash
echo "do JobB"
(3)新建 condition.flow
nodes:
- name: JobA
type: command
config:
command: sh JobA.sh
- name: JobB
type: command
dependsOn:
- JobA
config:
command: sh JobB.sh
condition: ${JobA:wk} == 1
(4)将 JobA.sh、JobB.sh、condition.flow 和 azkaban.project 打包成 condition.zip
(5)创建 condition 项目=》上传 condition.zip 文件=》执行作业=》观察结果
(6)按照我们设定的条件,JobB 会根据当日日期决定是否执行。
2.7 预定义宏案例
Azkaban 中预置了几个特殊的判断条件,称为预定义宏。
预定义宏会根据所有父 Job 的完成情况进行判断,再决定是否执行。可用的预定义宏如
下:
(1)all_success: 表示父 Job 全部成功才执行(默认)
(2)all_done:表示父 Job 全部完成才执行(失败、kill掉终、中止都叫完成)
(3)all_failed:表示父 Job 全部失败才执行
(4)one_success:表示父 Job 至少一个成功才执行
(5)one_failed:表示父 Job 至少一个失败才执行
1 案例
需求:
JobA 执行一个 shell 脚本
JobB 执行一个 shell 脚本
JobC 执行一个 shell 脚本,要求 JobA、JobB 中有一个成功即可执行
(1)新建 hdfs_to_ods_event_log.sh
(2)新建 dwd_event_base_log.sh
(3)新建 predefine.flow
nodes:
- name: hdfs_to_ods_event_log
type: command
config:
command: sh hdfs_to_ods_event_log.sh
- name: JobB
type: command
config:
command: sh JobB.sh
- name: dwd_event_base_log
type: command
dependsOn:
- hdfs_to_ods_event_log
- JobB
config:
command: sh dwd_event_base_log.sh
condition: one_success
(4)脚本文件、predefine.flow、predefine.project 文件,打包成 predefine.zip。 注意:没有 JobB.sh。
(5) 创建 predefine 项目=》上传 predefine.zip 文件=》执行作业=》观察结果
最终的执行结果如下:
2.8 嵌套工作流之间的依赖
相当于一个main workflow层次更清晰,更方便管理,在每一层可以统一设置参数。
目录中文件结构如下
|groupA
|--ga_1.sh
|--gn_2.sh
|groupB
|--gb_1.sh
|--gb_2.sh
|embedded.flow
|embedded.project
embedded.flow工作流定义如下
nodes:
- name: jobA
type: noop
dependsOn:
- groupA
- name: groupA
type: flow
config:
prop: value
dependsOn:
- groupB
nodes:
- name: jobA1
type: command
config:
command: sh ./groupA/ga_1.sh
- name: jobA2
type: command
config:
command: sh ./groupA/ga_2.sh
- name: groupB
type: flow
config:
prop: value
nodes:
- name: jobB1
type: command
config:
command: sh ./groupB/gb_1.sh
- name: jobB2
type: command
config:
command: sh ./groupB/gb_2.sh
打包上传到Azkaban的project,可以查看工作流的结构如下
实现了不同嵌套流之间的依赖
参考链接:Azkaban documentation! — Azkaban documentation