Azkaban Flow Parameters 参数设置与接收,实现按时间区间执行脚本
摘要
使用Azkaban
调试任务时,虽说可以在 UI
界面里可以添加参数,在 job
中如何接收这些参数,如何能让 job
可以跑一个时间段而不是一个时间?本文主要说说这两个问题以及我的解决方式。对于大数据朋友使用此功能补数很有帮助。
背景
最近公司在建设自己的数据仓库,需要使用 Azkaban
来作任务的调度。期间数据组的同事拿了两个桔子对我说:“帮我写个 shell
脚本吧”,故事由此开始。
他的需求是:
- 接收最多三个参数,第一个必传,为 sql 名,第二个参数不传表示跑前一天,传则跑指定的,有第三个参数则跑 第二个字段到第三个参数之间的所有时间
- 在
Azkaban
管理界面可配置添加这两个参数,第一个参数写job
时已经确认。
开始
接到这需求,我想这简单的 shell
应该没有问题,做到最后我后悔了。shell
简单没有问题,可是 Azkaban Flow Parameters
的配置真是太难用了。
先介绍下我们调度的主要流程:
- 有一些
job
可能他们之间有依赖关系,这些job
是type=command
的,会调用run_hive.sh
并传几个参数。 run_hive.sh
会接收这些参数,并执行hive -hivevar ...
- 调试完成,等待执行完成
基础调试脚本
于是简单写了如下脚本 run_hive.sh
:
##!/bin/sh
## 脚本参数注释:
## $1 sql 脚本名
## $2 开始时间
## $3 结束时间
if [ ! -n "$1" ];then
echo "Must be passed in the first parameter. The first parameter in the name of the SQL is to be performed."
exit
fi
begin_dt=`date -d yesterday +%Y-%m-%d`
if [[ $# -ge 2 ]]; then
echo $2 | grep -Eq "[0-9]{4}-[0-9]{2}-[0-9]{2}" && date -d $2 +%Y-%m-%d > /dev/null
if [[ $? -ne 0 ]]; then
echo "第二个参数不是时间格式 $2"
exit
fi
begin_dt=$2
fi
if [[ $# = 3 ]]; then
echo $3 | grep -Eq "[0-9]{4}-[0-9]{2}-[0-9]{2}" && date -d $3 +%Y-%m-%d > /dev/null
if [[ $? -ne 0 ]]; then
echo "第三个参数不是时间格式 $3"
exit
fi
end_dt=$3
fi
echo "------输入参数------"
echo "sql:$1"
echo "begin_dt:$begin_dt"
echo "end_dt:$end_dt"
echo "-------------------"
if [[ $# = 3 ]]; then
beg_s=`date -d "$begin_dt" +%s`
end_s=`date -d "$end_dt" +%s`
echo "处理时间范围:$begin_dt 至 $end_dt"
while [[ "$beg_s" -le "$end_s" ]]; do
day=`date -d @$beg_s +%Y-%m-%d`
echo "当前日期:$day"
hive -hivevar dt=${begin_dt} -f /path/to/$1.sql
beg_s=$((beg_s+86400));
done
else
hive -hivevar dt=${begin_dt} -f /path/to/$1.sql
fi
本地测试了一下,完美!可以只存一个参数,执行默认前一天;传两个,则跑指定时间的;传三个则跑指定时间段的。
修改 job
配置
我们的 job
修改后大致是这样的:
type=command
dependencies=dependencies_goods
p1=${begin_dt}
p2=${end_dt}
command=sh /path/to/run_hive.sh goods_pay_day ${p1} ${p2}
retries=3
retry.backoff=5000
配置 Flow Parameters
写好脚本,交给了大数据的同事,想让他测试一下。
他改好 job
后,打包了当前项目,之后下载到了本地,使用 Azkaban
的 UI
界面上传了这次打包的压缩包。
看着看着我想,要么再送个 《Azkaban
自动打包项目并上传》
之后让他尝试配置了一下:
执行,等待,成功!
正当我准备 事了拂衣去,深藏身与名
。 大数据朋友对我说,不传参数或只传一个,好像不生效。
…
寻找解决方案
这问题到最后都没有解决,只能通过 curl 来使用我之前的脚本。在 curl
脚本中加入了参数的判断。
我看 job
中的 command
命令是直接执行 shell
命令,我想可以在这里做文章。给 begin_dt
, end_dt
, p1
, p2
设置默认值都不能接收(注:可以使用 ${begin_dt=+2018-12-28}
来设置默认值)。而 Azkaban
不识别这种格式,直接当作字符串处理。
还尝试了其它很多方式,最后像我一点不懂 Azkaban
的,去看了官方这块的文档,依然没有解决。
官方中有一条 issues
中提及在 4.x
版本中会引入 backfill
兴许可以解决传递时间的问题,我只好放弃。
小结
写脚本还是可以解决一些问题的,虽然并没有彻底解决大数组同学的问题,不过倒是提供了一个思路。可以在写一个本地的命令行脚本,不使用 UI
界面的调度,直接转到命令行的操作。
可这样对他们来说更加不友好,没有进行下去。