任务的时间属性目前支持月、周、天、小时和分钟 5 种配置方式,本文将分别介绍配置方式和调度系统中的实例运行情况。
注意:
一个周期运行的任务,它的依赖关系的优先级 大于 时间属性。在时间属性决定的某个时间点到达时,任务实例不会马上运行,而是先检查上游是否全部运行成功。
1)上游依赖的实例没有全部运行成功 并且 定时运行时间已到,则实例仍为 未运行状态。
2)上游依赖的实例全部运行成功 并且 定时运行时间还未到,则实例进入 等待时间 状态。
3)上游依赖的实例全部运行成功 并且 定时运行时间已到,则实例进入 等待资源 状态准备运行。
在 DataWorks(数据工场,原大数据开发套件)中,当一个任务被成功提交后,底层的调度系统从 第二天开始,将会 每天按照该任务的时间属性生成实例,并根据上游依赖的实例运行结果和时间点运行。23:30 之后提交成功的任务从第三天开始才会生成实例。
注意:
若有一个任务需要每周一执行一次,那么只有运行时间是周一的情况下,该任务才会真正执行,运行时间非周一的情况下,该任务会空跑(直接将任务置为成功),不会实际运行。所以周调度任务,在测试/补数据的时候,需要选择 业务日期=运行时间-1。
天调度任务,即每天自动运行一次。新建周期任务时,默认的时间周期为 每天 0 点 运行一次,可根据需要自行指定运行时间点,例如下图指定每天 13 点运行一次。
导入、统计加工和导出任务,都是天任务,具体时间如上图 13 点。统计加工任务依赖导入任务,导出任务依赖统计加工任务,依赖配置如下图(统计加工任务 的依赖属性配置上游任务为 导入任务)所示:
上图的配置,调度系统会自动为任务生成实例并运行如下:
周调度任务,即每周的特定几天里每天在特定时间点自动运行一次。当到了没有被指定的日期时,为保证下游实例正常运行,系统也会生成实例但直接设置为运行成功,而不会真正执行任何逻辑,也不会占用资源。
如上图所示,每周一、周五两天生成的实例会正常的调度执行,而周二、三、四、六以及周日5天都是生成实例然后直接设置为运行成功。
上图的配置,调度系统会自动为任务生成实例并运行如下:
月调度任务,即每月指定的特定几天里每天在特定时间点自动运行一次。当到了没有被指定的日期时,为保证下游实例正常运行,系统也会每天生成实例但直接设置为运行成功,而不会真正执行任何逻辑,也不会占用资源。
如上图所示,每月 1 日生成的实例会正常的调度执行,其他日期每天都是生成实例并直接设为运行成功。
上图的配置,调度系统会自动为任务生成实例并运行如下:
小时调度任务,即每天指定的时间段内按 N*1 小时的时间间隔运行一次,比如每天 1 点到 4 点的时间段内,每 1 小时运行一次。
注意:
时间周期按 左闭右闭 原则计算,比如配置为从 0 点到 3 点的时间段内,每隔 1 个小时运行一次,表明时间区间为 [00:00,02:59],间隔为 1 小时,调度系统将会每天生成 4 个实例,分别在0点/1点/2点运行。
如上图的配置,表示每天 00 点整到 23 点 59 分这个时间段内,每隔 6 小时会自动调度一次,因此调度系统会自动为任务生成实例并运行如下:
分钟调度任务,即每天指定的时间段内按 N* 指定分钟的时间间隔运行一次,目前能支持的最短时间间隔为每 5 分钟运行一次。
如上图配置,表示每天00点整到23点59分这个时间段内,每隔30分钟会自动调度一次,因此调度系统会自动为任务生成实例并运行如下:
Q: 周/月任务没有被指定的日期怎么办?
A: 周调度和月调度的任务,存在部分日期生成实例然后直接设置为成功的情况,此时可以看到日志中没有生成任何信息的提示,这是正常的情况。
Q: 任务被配置为暂停是否生成实例?
A: 当一个任务被配置为 暂停 时,调度系统仍会每天按时间属性为该任务生成对应的一个或多个实例,但这些实例在定时时间到达时不会真正运行其中的代码,而是直接被设置为运行失败,以保证下游实例不会被触发运行。
被直接设置为运行失败的实例,实际并没有执行其中的代码,因此没有日志信息产生,实例运行情况如下图所示:
Q: 任务被删除,实例是否受影响?
A: 当一个任务运行一段时间后被 删除 时,由于调度系统每天会按时间属性为该任务生成对应的一个或多个实例,实例不会被删除。因此当这些实例在任务被删除了之后才被触发运行时,会由于找不到需要运行的代码而失败,报错信息如下所示:
Q: 想在每月的最后一天计算当月数据怎么办?
A:目前系统不支持配置 每月最后一天,因此如果时间周期选择 每月 31 日,那么在有 31 日的月份会有一天调度,其他日期都是生成实例然后直接设为运行成功。
需要统计每个月的数据时,建议选择每月的 1 日运行,计算上个月的数据。
为使任务自动周期运行时能动态适配环境变化,DataWorks(数据工场,原大数据开发套件)提供了参数配置的功能,如下表所示:
参数类型 | 设置方式 | 适用类型 | 参数编辑框示例 |
系统参数 bdp.system.bizdate 和bdp.system.cyctime | 在调度系统中运行时,无须在编辑框设置,可直接在代码中引用 ${bdp.system.bizdate}和${bdp.system.cyctime}, 系统将自动替换这两个参数的取值 | 全部节点类型 | 无 |
自定义参数 | 在代码中引用${key1},${key2}, 然后在“参数”编辑框以如下方式设置 “key1=value1 key2=value2”, | 除Shell外的其他节点类型 | 常量参数:param1=”abc” param2=1234; 变量参数:param1=$[yyyymmdd], 结果将基于bdp.system.cyctime的取值计算 |
在代码中引用$1 $2 $3, 然后在“参数”编辑框以如下方式设置: “value1 value2 value3” | Shell类型 | 常量参数:”abc” 1234; 变量参数:$[yyyymmdd], 结果将基于bdp.system.cyctime的取值计算 |
DataWorks(数据工场)提供了 2 个系统参数,定义如下:
${bdp.system.cyctime}:定义为一个实例的定时运行时间,默认格式为:yyyymmddhh24miss。
${bdp.system.bizdate}:定义为一个实例计算时对应的业务日期,业务日期默认为运行日期的前一天,默认以 yyyymmdd 的格式显示。
从定义可知,运行时间和业务日期有如下计算公式:运行时间=(业务日期+1)+定时时间。
若使用系统参数,无需在编辑框设置,直接在代码中引用 ${bdp.system.bizdate} 和 ${bdp.system.cyctime} 即可,系统将自动替换代码中对这两个参数的引用字段。
注意:
一个周期任务的 调度属性,配置的是 运行时间 的定时规律,因此可以根据实例的定时运行时间反推业务日期,从而得知每个实例中这两个参数的取值。
设置一个 ODPS_SQL 任务为小时调度,每天 00:00-23:59 时间段里每隔 1 小时执行一次,若想在代码中使用系统参数,则可按如下步骤进行操作:
1)在代码中直接引用系统参数。节点代码如下:
insert overwrite table tb1 partition(ds ='20150304') select c1,c2,c3 from ( select * from tb2 where ds ='${bdp.system.cyctime}') t full outer join( select * from tb3 where ds = '${bdp.system.bizdate}') y on t.c1 = y.c1;
2)设置时间周期为每隔 1 小时运行一次。
3)设置系统参数的编辑框为空。
4)查看系统运行的实例日志。有 4 种方式可以触发运行,其中 3 种可以生成实例,详情请参见 数据开发概述。生成实例的运行模式可以比较好的观察到系统对参数的计算。以系统周期自动运行为例,代码提交后第二天在运维中心可以看到系统自动按时间周期生成的运行实例。例如:在 2017 年 07 月 16 日这一天,调度系统为该任务生成了 24 个运行实例。业务日期应当全部为 2017 年 07 月 15 日(运行日期-1天),因此 ${bdp.system.bizdate} 全部显示为 20170715。运行时间则为 (运行日期+定时时间),因此 ${bdp.system.cyctime} 显示为 20170716000000+每个实例自己的定时时间。每个实例的运行日志打开后搜索代码中的替换情况如下:
① 第一个实例定时时间为 2017-07-16 00:00:00,则 bdp.system.bizdate 替换的结果为 20170715; bdp.system.cyctime 替换的结果为 20170716000000。
② 第二个实例定时时间为 2017-07-16 01:00:00,则:bdp.system.bizdate 替换的结果为 20170715;bdp.system.cyctime 替换的结果为 20170716010000。
③ 以此类推,第 24 个实例定时时间为 2017-07-16 23:00:00,则:bdp.system.bizdate 替换的结果为 20170715;bdp.system.cyctime 替换的结果为 20170716230000。
使用自定义参数的场景:
非 Shell 类型的脚本或任务:需要先在代码中编辑 ${key1},${key2},然后在 参数 编辑框输入 “key1=value1 key2=value2” 方可生效。
Shell 类型的脚本或任务:需要先在代码中编辑 $1 $2 $3,然后在 参数 编辑框 “value1 value2 value3” 方可生效。
其中,value 的计算分为两种类型:
1)常量:直接替换的字符串或数字,例如“key1=1234 key2=abcdefg”。
2)变量:基于 bdp.system.cyctime 取值计算出的取值,例如“key1=$[yyyy]”表示按 bdp.system.cyctime 的值取年的部分作为结果替换该参数。
备注:关于 bdp.system.cyctime 的取值,请参见系统参数的说明。
可供参考的变量参数配置方式如下:
后N年:$[add_months(yyyymmdd,12*N)] 前N年:$[add_months(yyyymmdd,-12*N)] 后N月:$[add_months(yyyymmdd,N)] 前N月:$[add_months(yyyymmdd,-N)] 后N周:$[yyyymmdd+7*N] 前N周:$[yyyymmdd-7*N] 后N天:$[yyyymmdd+N] 前N天:$[yyyymmdd-N] 后N小时:$[hh24miss+N/24] 前N小时:$[hh24miss-N/24] 后N分钟:$[hh24miss+N/24/60] 前N分钟:$[hh24miss-N/24/60]
注意:
i)请以中括号 [] 编辑自定义变量参数的取值计算公式,例如 key1=$[yyyy-mm-dd]。
ii)默认情况下,自定义变量参数的计算单位为天。例如 $[hh24miss-N/24/60] 表示 (yyyymmddhh24miss-(N/24/60 * 1天)) 的计算结果,然后按 hh24miss 的格式取时分秒。
iii)使用 add_months 的计算单位为月。例如 $[add_months(yyyymmdd,12 N)-M/24/60] 表示 (yyyymmddhh24miss-(12N 1月))-(M/24/60 1天) 的结果,然后按 yyyymmdd 的格式取年月日。
设置一个 ODPS_SQL 类型的任务为按天调度,每天 01:00 执行一次,若想在代码中使用一个自定义常量参数 tablename 和一个自定义变量参数 ct,则可按如下步骤进行操作:
① 在代码中引用自定义变量名。
insert overwrite table ${tablename} partition(ds=${ct}) select c1,c2,c3 from ( select * from tb2 where ds ='${bdp.system.cyctime}') t full outer join( select * from tb3 where ds = '${bdp.system.bizdate}') y on t.c1 = y.c1;
② 设置时间周期为每天 1 点运行。
③ 在 参数 编辑框设置自定义参数的计算公式。
④ 查看系统运行的实例日志。
有 4 种方式可以触发运行,其中 3 种可以生成实例,详情请参见 数据开发概述。生成实例的运行模式可以比较好的观察到系统对参数的计算。
以系统周期自动运行为例,代码提交后第二天在运维中心可以看到系统自动按时间周期生成的运行实例。
例如在 2017 年 07 月 17 日这一天,调度系统为该任务生成了 1 个运行实例。运行日期应当全部为 2017 年 07 月 17 日(生成实例当天),因此 ${bdp.system.cyctime} 取值应当为 20170717。
此时打开实例的运行日志,可以看到代码中 ${tablename} 被替换为常量 t_table_001,${ct}被替换为 2017-07-15,也就是运行日期的前两天。
设置一个 ODPS_SQL 任务为按小时调度,每天 00:00-23:59 时间段里每隔 1 小时执行一次,想要在代码中使用两个关于小时的自定义变量参数 thishour 和 lasthour,则应当按如下操作:
① 在代码中引用自定义变量名。
insert overwrite table tb1 partition(ds ='20150304') select c1,c2,c3 from ( select * from tb2 where ds ='${thishour}') t full outer join( select * from tb3 where ds = '${lasthour}') y on t.c1 = y.c1;
② 配置时间周期为每隔 1 小时运行一次。
③ 在 参数 编辑框设置自定义参数的计算公式。
自定义参数配置如下:
thishour=$[yyyy-mm-dd/hh24:mi:ss] lasthour =$[yyyy-mm-dd/hh24:mi:ss-1/24]
④ 查看系统运行的实例日志。有 4 种方式可以触发运行,其中 3 种可以生成实例,详情请参见 数据开发概述。生成实例的运行模式可以比较好的观察到系统对参数的计算。以系统周期自动运行为例,代码提交后第二天在运维中心可以看到系统自动按时间周期生成的运行实例。例如在 2017 年 07 月 16 日这一天,系统应当为该任务生成 24 个实例。运行日期为 2017 年 07 月 16 日(生成实例当天),因此 ${bdp.system.cyctime} 取值应当为 20170716。此时打开各实例的运行日志,应当看到如下替换结果:
i)第一个实例定时时间为 2017-07-16 00:00:00,那么 thishour 替换的结果为 2017-07-16/00:00:00,lasthour 替换的结果为 2017-07-15/23:00:00。
ii)第二个实例定时时间为 2017-07-16 01:00:00,那么 thishour 替换的结果为 2017-07-16/01:00:00,lasthour 替换的结果为 2017-07-16/00:00:00。
iii)以此类推第 24 个实例定时时间为 2017-07-16 23:00:00,那么 thishour 替换的结果为 2017-07-16/23:00:00,lasthour 替换的结果为 2017-07-16/22:00:00。
设置一个 Shell 类型的任务为按天调度,每天 01:00 执行一次,若想在代码中使用一个自定义常量参数 myname 和一个自定义变量参数 ct,则可按如下步骤进行操作:
① 在代码中引用自定义变量名。
其中的代码如下:
echo "hello $1, two days ago is $2, the system param is ${bdp.system.cyctime}";
② 设置时间周期为每天 1 点运行。
③ 在 参数 编辑框设置自定义参数的计算公式。
系统参数无需提供计算公式,自定义参数需要按 $value1 $value2 $value3。
④ 查看系统运行的实例日志。
有 4 种方式可以触发运行,其中 3 种可以生成实例,详情请参见 数据开发概述。生成实例的运行模式可以比较好的观察到系统对参数的计算。
以系统周期自动运行为例,代码提交后第二天在运维中心可以看到系统自动按时间周期生成的运行实例。
例如在 2017 年 07 月 17 日这一天,调度系统为该任务生成了 1 个实例。运行日期应当全部为 2017 年 07 月 17 日(生成实例当天),因此 ${bdp.system.cyctime} 取值应当为 20170717。
此时打开实例的运行日志,可以看到代码中 $1 被替换为常量 abcd,$2 被替换为 2017-07-15,也就是运行日期的前两天, ${bdp.system.cyctime} 被替换为 20170717010000。
Q: 表的分区格式为 pt=yyyy-mm-dd hh24:mi:ss,但是调度参数中不允许配置空格,我该如何配置$[yyyy-mm-dd hh24:mi:ss]的格式呢?
A: 使用两个自定义变量参数 datetime=$[yyyy-mm-dd]、 hour=$[hh24:mi:ss],分别获取日期和时间,然后在代码中拼接为 pt=”${datetime} ${hour}” (注意拼接的两段自定义参数之间需要空格隔开)。
Q: 在代码中表的分区为 pt=”${datetime} ${hour}”,希望执行的时侯取上个小时的数据。使用两个自定义变量参数 datetime=$[yyyymmdd]、 hour=$[hh24-1/24],分别获取日期和时间可以满足需求。但是 0 点运行的实例,计算结果会变成当天的 23 点,实际应当是前一天的 23 点,怎么办?
A: 参数的计算公式稍作修改,datetime 修改为 $[yyyymmdd-1/24],hour 的计算公式不变仍为 $[hh24-1/24]。计算结果如下,即可满足需求:
如果一个实例的定时时间是2015-10-27 00:00:00,减1小时就是昨天,所以$[yyyymmdd-1/24]的值是20151026,$[hh24-1/24]的值是23;
如果一个实例的定时时间为2015-10-27 01:00:00的实例,减1小时还是今天,所以$[yyyymmdd-1/24]的值是20151027,$[hh24-1/24]的值是00;
DataWorks(数据工场)提供了 4 种运行方式,详情请参见 数据开发概述。这四种方式下系统参数计算方式如下:
1)数据开发页面运行:需要在参数配置页面 临时 赋值以保证运行。但该赋值不会保存为任务的属性,因此不会对其他3种运行方式起作用。
2)系统自动周期运行:不需要在参数编辑框做任何配置,调度系统会根据当前实例的定时运行时间自动替换。
3)测试运行/补数据运行:触发时需要指定 业务日期,可根据上述计算公式推断定时运行时间,从而得知各实例中这两个系统参数的取值。
在调度配置中,会需要配置两个任务级别的依赖:依赖属性和跨周期依赖。
i)自动推荐:系统自动扫描节点代码解析出来源表和目标表,从而推荐来源表是从哪个任务产出,只有 SQL 类型节点任务和工作流任务有这个功能,同时也只能解析到 SQL 任务产出的表 。
ii)所属项目:当前组织内所有项目空间,可在下拉列表中进行选择。
iii)上游任务:对应所属项目空间中的任务,用来设置当前任务的上游任务,非必填项。支持工作流名称模糊匹配查询 。
一个工作流可以依赖多个上游工作流,同样,一个工作流可被多个工作流依赖。依赖属性为非必填项,当下游工作流需依赖上游工作流产出数据,则可配置依赖关系。
比如:有一个需求,在 A 工作流中配置的节点达到上限了,还是没有完成需求。那么就可以创建 B 工作流,继续配置节点任务,然后将 A 工作流设置成 B 工作流的上游任务,运行的时候,便会先运行 A 再运行 B。
配置节点/工作流任务的跨周期依赖,如:天调度任务中,今天需要执行的数据依赖本任务昨天执行的数据,那么可以配置依赖昨天任务的周期,这样一来,昨天的实例必须先执行成功,今天的实例才可以调度起来,这种依赖主要是体现在任务调度实例的依赖 。关于不同周期调度依赖的最佳操作实践,请参见 不同周期调度依赖配置。
跨周期依赖说明:
i)不依赖上一调度周期:所有任务默认选择该选项,即不依赖任何任务的上周期实例。
ii)自依赖,等待本任务上一调度周期结束,才能继续运行:应用场景:任务 A 当前周期数据来源依赖于任务 A 上周期执行的结果;或者小时/分钟调度任务 A 不允许实例并行。
iii)等待下游任务的上一周期结束,才能继续运行:依赖第一层子任务的上周期。这种应用场景不多,选择此项,后续该任务一旦被其他任务直接依赖则实例都依赖所有第一层子任务的上周期实例。
iv)等待自定义任务的上一周期结束,才能继续运行:应用场景:天任务 A 依赖一个数据是天任务 B 昨天产出的。
① 依赖属性配置的调度依赖是同周期依赖和跨周期依赖不冲突。任务 A 可以配置依赖属性依赖任务 B,也可以配置跨周期依赖依赖 B,如此任务 A 既依赖任务 B 本周期也依赖任务 B 上周期。
② 若任务 A 是小时/分钟调度,任务 B 是天调度,任务 B 配置依赖任务 A 的上周期,那么当天任务 B 的实例会依赖任务 A 昨天的所有实例。
③ 若任务 A 和 B 都是小时/任务调度,调度周期一样,任务 B 配置依赖任务 A 的上周期,则任务 B 每个实例都将依赖任务 A 昨天的所有实例和任务 A 与任务 B 同周期的前一个周期实例。
④ 如果天调度任务 A 配置跨周期依赖任务 B 的上周期,那么对任务 A 进行补数据的时候,补数据实例会去依赖任务 B 自动调度上周期实例,如果自动调度的上周期实例不存在则不依赖。
⑤ 长周期依赖短周期配置方式的详细内容请参见 不同周期调度依赖配置 。