背景
技术调研三个任务调度框架 ElasticJob、XXL-Job,这周轮到 Azkaban 了。按照官方操作文档编译部署,最后启动一个任务还是很波折,不是 Preparing 就是 Killing ,还有一种 Failed 状态,就是没有 Success 。
根源竟然是没有对 Executor 执行 active 请求,官方文档上是有一句激活执行器的请求,看文档的时候还纳闷,如果不执行会怎么样呢?也不知道执行器端口,就没执行,结果真的掉坑了。
编译
第一步,下载源码,最新版本 4.0.0 ,上传到 Linux 服务器上。
第二步,执行编译命令 ./gradlew installDist
等待编译完成,真的很慢,要超级有耐心呐!
部署中心和执行器启动
第一步,部署 azkaban-web-server 和 azkaban-exec-server ,将编译后的 build/install 下的这两个模块的内容上传到某个 Linux 服务器上。
第二步,数据库环境准备,在 MySQL 数据库中创建数据库 azkaban,并将 azkaban-db 目录下的 SQL 文件导入到该数据库中。
第三步,修改 azkaban-exec-server 的配置文件 azkaban.properties,数据库连接、时区【很重要】、控制中心地址【这个貌似没有用】。
default.timezone.id=Asia/Shanghai
azkaban.webserver.url
database.type=mysql
mysql.port=3306
mysql.host=XX
mysql.database=azkaban
mysql.user=root
mysql.password=XX
启动执行器并激活
./bin/start-exec.sh
执行器启动后,数据库的 executors 表会多一条记录,active 状态为 0,记录中有 host 和 port 信息,根据这两项信息发起 REST 激活请求:
curl http://localhost:port/executor?action=activate
第四步,修改 azkaban-web-server 的配置文件 azkaban.properties,数据库连接、时区【很重要】启动
default.timezone.id=Asia/Shanghai
jetty.port=8092
database.type=mysql
mysql.port=3306
mysql.host=XX
mysql.database=azkaban
mysql.user=root
mysql.password=XX
jetty 默认端口可能被其他应用占据,换一个端口,然后进入根目录,启动 web-server :
./bin/start-web.sh
查看 logs 目录下的日志,有 Server started 说明启动成功:
测试任务执行
创建了一个很简单的 job 之后,一直报错,有大量异常
调度中心异常日志显示:
Caused by: java.io.IOException: executor became inactive before setting up the flow 27
azkaban.executor.ExecutorManagerException: azkaban.executor.ExecutorManagerException: executor became inactive before setting up the flow 27
手动激活执行器后:
curl http://localhost:46352/executor?action=activate
异常消失:
包含子流的任务
一个 Project 只能上传一个 .zip 文件,但是文件中可以通过 type=flow 定义多个流:
创建子工作流的流程参考资料。
思考问题:包含子流的那个工作流在调度执行子流时,是否需要按照调度周期执行呢?
测试结论:流 d 到达调度时间后,会执行依赖的 flow c ,即使还没有到达 c 的调度时间。此外, c 也按自己的调度周期,每隔五分钟执行一次:
Azkaban 的并行调度策略
同一个 flow 如果正在执行,而下一轮调度周期又到达了,那么任务的调度会如何处理呢?执行策略有三种,即并行配置:
Azkaban 的疑惑
多执行器部署场景下,是否支持任务分片执行呢? Right click on the jobs to disable and enable jobs in the flow. 右键 Disable all 了之后会怎么样呢?对应任务就不会执行了吗? Azkaban 执行任务流很流畅,貌似不能对任务进行分片。
每次环境部署都不会很顺畅,虽然按照官方文档操作,总是会遇到一些小问题,也是真够神奇的!
主要是三个小问题:
- web-server 端口问题,默认端口被其他应用占据了。
- 执行器和调度中心的启动顺序,如果一个激活状态的执行器都没有,web-server 就无法启动成功。直接改 executors 表的 active 字段虽然能让 web-server 正确启动,但是后面调度任务的时候会提示没有激活的执行器。
- 执行器启动后需要通过 REST 请求激活
Azkaban 的任务调度器竟然不会自动激活,这一点真的太不友好了。
ElasticJob 和 XXL-Job 都有自动注册上下线的功能,而 Azkaban 启动执行器的时候,只会添加一条 executors 记录,但是状态为 0 ,不知道为何这样设计?这个小问题导致一个简单的 Job 一直得不到正确调度。