简介
Azkaban是在Linkedln上创建的用于运行Hadoop作业的批处理工作流作业调度系统。通过作业之间的依赖性完成工作流程,并可以提供易于使用的web用户界面来维护和跟踪用户的工作流程。
特点
- 与任何版本的Hadoop兼容(oozie依赖于Hadoop版本)
- 易于使用的Web UI界面(oozie的Web界面功能较少)
- Web界面支持工作流上传操作(oozie界面没有)
- 工作流定时调度
- 认证和授权(oozie没有这个功能)
- 通过电子邮件通知失败和成功(oozie也没有这个功能)
- 作业失败重试策略
作业类型
Azkaban的作业类型插件支持任何一种作业类型,但是内置插件command类型,适用于大多数hadoop作业。
- command
- hadoopshell
- java
- hadoopJava
- pig
- hive
- 用户自己创建的作业类型
创建工作流
官方网站上使用Azkaban Flow2.0版本,Flow1.0版本将来会弃用
Flow 2.0 Basics
Step 1:
创建文件flow20.project,文件内容如下,表明是一个Flow2.0版本的Azkaban工程
azkaban-flow-version: 2.0
Step 2:
创建文件basic.flow,用来记录工作流,文件内容如下:
nodes:
- name: jobA
type: command
config:
command: echo "This is an echoed text."
nodes:表示单个作业
name:作业名称
type:作业类型
config:作业的一些配置
Step 3:
将Step1和Step2中的文件打包为.zip文件,在Azkaban的web页面上传该zip文件到已经创建的工程中
Job Dependencies
使用dependsOn标签添加依赖作业,如下:
nodes:
- name: jobC
type: noop
# jobC depends on jobA and jobB
dependsOn:
- jobA
- jobB
- name: jobA
type: command
config:
command: echo "This is an echoed text."
- name: jobB
type: command
config:
command: pwd
Job Config
作业配置使用key:value对表示,如下是一个Pig作业:
nodes:
- name: pigJob
type: pig
config:
pig.script: sql/pig/script.pig
作业流嵌套
作业流中可以嵌套别的作业流,type声明为flow即可,如下:
nodes:
- name: embedded_flow
type: flow
config:
prop: value
nodes:
- name: jobB
type: noop
dependsOn:
- jobA
- name: jobA
type: command
config:
command: pwd
使用Azkaban的Web页面执行工作流
执行工作流界面
可以右击鼠标设置工作流中单个作业是否可以运行(Enable和Disable)选择Disable,那么在执行到该作业时,该作业将会被跳过。
通知选项
工作流执行成功或失败时的通知设置
失败通知
First Failure:检测到作业节点第一次失败时立即发送失败邮件
Flow Failure:当整个工作流运行结束时,若其中有作业节点失败,会在运行结束时才发送失败邮件
失败配置
Finish Current Running:当前节点失败,则执行完当前节点后,不再执行后续节点(挂起当前作业执行计划)
Cancel All:立即结束正在运行的节点,工作流执行失败(终止当前作业执行计划)
Finish All Possible: 当前节点失败,还会执行后续节点(继续执行下一节点)
并行选项
Skip Execution:如果相同的工作流正在执行,那么不会执行该作业流新发起的执行请求
Run Concurrently:不论相同的工作流是否在执行,都会执行新发起的执行请求(从第一个作业节点开始执行)
Pipeline:如果新发起的执行请求,与正在执行的工作流相比,新增了作业节点,那么新开始的执行会跳过已经执行过的作业节点,直接执行新增的作业节点
工作流参数
这里设置的参数会覆盖作业的全局属性,但是不会覆盖单个 作业节点的私有属性
调度配置
如下图所示,Azkaban定时调度精度是min,而华为云数据湖工厂定时调度的精度可以达到s级。
Azkaban的cron表达式语法是Quartz格式(QUARTZ),只是精度是min级。Flexible Schdule Wiki详细介绍了如何使用Azkabzn3.3版本的Fiexible Scheduling 特性
SLA
设置SLA警报电子邮件,应用与单个作业或工作流,如果执行时间超过时间阈值,可以自动终止作业或工作流。如果工作流配置了重试策略,此时会根据这个配置重试
作业编辑
通过Web页面可以编辑作业属性如:类型和依赖关系,以及工作流的全局属性。
条件工作流
条件工作流允许用户指定条件,当满足指定的条件时,工作流才会执行。类似于华为云数据湖工厂中的条件表达式。
使用YAML文件定义所需要的条件。
如何定义一个条件?
有效的條件是指运行时参数和作业状态宏的组合。逻辑运算符用来进行条件的组合
支持的逻辑运算符包括:== != > >= < <= && || !
作业运行时参数
$ {jobName:param}用来表示运行时参数,运行时参数可以与String 或数字进行比较。用户需要将参数值写入$ {JOB_OUTPUT_PROP_FILE}
作业状态宏
支持的状态宏:
- all_success(default)
- all_done
- all_failed
- one_success(at least one parent job successed)
- one_failed(at least one parent job failed)
每个状态宏中的作业状态:
- all_done:FAILED KILLED SUCCESSED SKIPPED FAILED_SUCCESSED CANCALLED
- all_success / one_success: SUCCESSED SKIPPED FAILED_SUCCESSED
- all_failed / one_failed: FAILED KILLED CANCELED
不允许用户在一个条件中组合多个作业状态宏,这样会导致冲突
examples:
${JobA:param1} == 1 && ${JobB:param2} > 5
one_success
all_done && ${JobC:param3} != "foo"
(!{JobD:param4} || !{JobE:parm5}) && all_success || ${JobF:parm6} == "bar"
下面的例子中JobA将运行时参数写入文件 $JOB_OUTPUT_PROP_FILE,JobB和JobC使用JobA的运行时参数作为条件进行判断,这里JobB将会被执行,因为JobC条件不满足,一旦JobB执行完成,就直接执行JobD,JobD的条件是只要Job B和JobC中有一个执行成功,条件就满足。
可以为作业和子工作流(嵌套)设置运行条件
sample.flow
nodes:
- name: JobA
type: command
config:
command: bash ./write_to_props.sh
- name: JobB
type: command
dependsOn:
- JobA
config:
command: echo “This is JobB.”
condition: ${JobA:param1} == 1
- name: JobC
type: command
dependsOn:
- JobA
config:
command: echo “This is JobC.”
condition: ${JobA:param1} == 2
- name: JobD
type: command
dependsOn:
- JobB
- JobC
config:
command: pwd
condition: one_success
write_to_props.sh
echo '{"param1":"1"}' > $JOB_OUTPUT_PROP_FILE
工作流驱动依赖插件
Kafka事件驱动
Azkaban支持scheduling和Ajax API驱动。还有一些作业需要根据需要自动执行(被触发)。Azkaban引入了一种新特性,就是事件驱动,定义了在Kafka事件到达时触发作业执行。使用户可以定义工作流所依赖的事件,一旦所有事件准备就就绪,就可以触发工作流程执行。
Apache Kafka是一个发布和订阅数据流系统。通过使用Kafka,对Kafka事件进行了正则表达式匹配。
在Azkaban中使用事件驱动
- Build
Azkaban使用Gradle进行编译(使用Gradle包装器gradlew运行时自动下载),并且需要Java8 或更高版本。
使用如下命令编译工作流事件依赖插件,该命令需要在/az-flow-trigger-dependency-type/kafka-event-trigger文件夹执行
# Build Azkaban
../../gradlew build
# Clean the build
../../gradlew clean
# Build without running tests
../../gradlew build -x test
-
Server配置
编译之后在conf中声明插件目录。以单server为例,在conf/azkaban.properties文件中修改azkaban.dependency.plugin.dir属性,该属性需要设置为事件驱动jar包的路径。 -
Database配置
-
以下四个属性需要在conf/zakaban.private.properties中配置。以单server为例,
Properties |
---|
mysql.user |
mysql.password |
org.quartz.dataSource.quartzDS.user |
org.quartz.dataSource.quartzDS.password |
- 事件驱动插件配置
在Azkaban的依赖插件目录中,需要包含事件驱动jar包和dependency.properties两个文件。
必选的属性:
– dependency.classpath:jar包的绝对路径,帮助Azkaban识别插件地址
– dependency.class:trigger.kafka.KafkaDependencyCheck。帮助Azkaban工作流驱动实例进行整合
– kafka.broker.url:你的Kafka代理的URL和端口号 - 事件驱动实例配置
事件驱动时工作流配置的一部分,每个工作流最多只能配置一个事件驱动。
通过Hadoop DSL支持定义事件驱动。事件驱动需要与用户上传的zip项目一起配置。事件驱动由event dependencies、max wait time和schedule组成。看个例子:
– Max Wait Time:等待多久取消作业运行
– Trigger.schedule:cron表达式用来表示工作流的调度时间
– triggerDepedendies:如果满足所有预定的依赖条件,事件将会被触发
因此,上面的例子中,需要满足三个条件事件才可以被触发