针对数据仓库中的任务脚本我们前面已经整理过了,任务脚本还是比较多的,针对初始化表的脚本只需要执行一次即可,其它的脚本需要每天都执行一次,这个时候就需要涉及到任务定时调度了。
Crontab调度器的使用
咱们前面在学习Linux的时候学过一个crontab调度器,通过它可以实现定时执行指定的脚本。
针对我们这个数据仓库中的这些脚本使用crontab进行调度是可以的
但是需要注意一点:这些任务之间是有一些依赖关系的,从大的层面上来说,dwd层的任务需要等ods层的任务执行成功之后才能开始执行
那crontab如何知道任务之间的依赖关系呢?
crontab是无法知道任务之间的依赖关系的,我们只能间接实现
举个例子:针对MapReduce任务和Spark任务,任务执行成功之后,在输出目录中会有一个success标记文件,这个文件表示这个任务成功的执行结束了。
此时如果我们使用crontab调度两个job,一个jobA,一个jobB,先执行jobA,jobA成功执行结束之后才能执行jobB,这个时候我们就需要在脚本中添加一个判断,判断jobA的结果输出目录中是否存在success文件,如果存在则继续执行jobB,否则不执行,并且告警,提示jobA任务执行失败。
那我们现在执行的是hive的sql任务,sql任务最终不会在输出目录中产生success文件,所以没有办法使用这个标记文件进行判断,不过sql任务会产生数据文件,数据文件的文件名是类似000000_0这样的,可能会有多个,具体的个数是由任务中的reduce的个数决定的,我们也可以选择判断这个数据文件是否存在来判断任务是否成功执行结束。
注意了:针对SQL任务虽然可以通过判断数据文件来判定任务是否执行成功,不过这种方式不能保证100%的准确率,有可能会存在这种情况,任务确实执行成功了,但是在向结果目录中写数据文件的时候,写了一半,由于网络原因导致数据没有写完,但是我们过来判断000000_0这个文件肯定是存在的,那我们就误以为这个任务执行成功了,其实它的数据是缺失一部分的,不过这种情况的概率极低,可以忽略不计。
如果项目中的定时任务有很多,使用crontab虽然可以实现任务依赖的功能,但是管理起来不方便,
crontab没有提供图形化的界面,使用起来比较麻烦
针对一些简单的定时任务的配置,并且任务比较少的情况下使用crontab是比较方便的。
Azkaban调度器的使用
Azkaban介绍
在实际工作中如果需要配置很多的定时任务,一般会采用一些支持界面操作的调度器,例如:Azkaban、Ooize
Azkaban是一个轻量级的调度器,使用起来比较简单,容易上手。
Ooize是一个重量级的调度器,使用起来相对比较复杂。
在这里我们主要考虑易用性,所以我们选择使用Azkaban。
下面我们来快速了解一下Azkaban,以及它的用法。
Azkaban是由Linkedin开源的一个批量工作流任务调度器。用于在一个工作流内以一个特定的顺序运行一组工作和流程。
Azkaban定义了一种KV文件格式来建立任务之间的依赖关系,并提供一个易于使用的web用户界面维护和跟踪你的工作流。
安装部署
官网下载的Azkaban是源码,需要编译,没有提供二进制文件。
下载
wget https://github.com/azkaban/azkaban/archive/refs/tags/3.73.0.tar.gz
安装Git
yum ‐y install git
yum ‐y install gcc‐c++
修改azkaban目录下的build.gradle文件,修改allprojects节点配置,指定仓库地址为阿里云仓库
allprojects {
apply plugin: 'jacoco'
repositories {
maven {
url 'https://maven.aliyun.com/repository/public/'
}
mavenLocal()
mavenCentral()
}
}
开始编译、安装并跳过测试阶段
./gradlew build installDist -x test
报错
Exception in thread "main" javax.net.ssl.SSLException: java.lang.RuntimeException: Unexpected error: java.security.InvalidAlgorithmParameterException: the trustAnchors parameter must be non-empty
at sun.security.ssl.Alerts.getSSLException(Alerts.java:214)
at sun.security.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1958)
at sun.security.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1915)
at sun.security.ssl.SSLSocketImpl.handleException(SSLSocketImpl.java:1898)
在windows下也尝试了,也不行,最终在网上找到了一个别人编译好的(版本3.36.0),azkaban 安装,直接使用。
部署
在这里我们就使用Azkaban的solo模式部署。
solo模式属于单机模式,那对应的Azkaban也支持在多台机器上运行。
solo模式的优点:
- 易于安装:无需MySQL示例。它将H2打包为主要的持久存储。
- 易于启动:Web服务器和执行程序服务器都在同一个进程中运行。
- 全功能:它包含所有Azkaban功能。
修改Azkaban的时区为上海时区,修改监听端口为9091,conf/azkaban.properties
default.timezone.id=Asia/Shanghai
jetty.port=9091
启动
bin/azkaban-solo-start.sh
停止
bin/azkaban-solo-shutdown.sh
启动成功之后,azkaban会启动一个web界面,监听的端口是9091
账号密码默认为 azkaban/azkaban
提交独立任务
先创建一个Project
向test项目中提交任务
创建一个文件hello.job,文件内容如下:
# hello.job
type=command
command=echo "Hello World!"
这里面的#号开头表示是注释
type:任务类型,这里的command表示这个任务执行的是一个命令
command:这里的command是指具体的命令
将hello.job文件添加到一个zip压缩文件中,hello.zip。
将hello.zip压缩包提交到刚才创建的test项目中
此时test项目中就包含hello这个任务,点击execute flow执行
此时这个任务执行一次就结束了,如果想要让任务定时执行,可以在这配置。
这就将test项目中的hello.job配置了定时任务。
其实我们会发现这里面的定时任务的配置格式和crontab中的一样。
提交依赖任务
先创建一个文件first.job
# first.job
type=command
command=echo "Hello First!"
再创建一个文件second.job,这里面通过dependencies属性指定了任务的依赖关系,后面的first表示依赖的任务的文件名称
# second.job
type=command
dependencies=first
command=echo "Hello Second!"
最后将这两个job文件打成一个zip压缩包