大数据开发过程中常遇到不同运行周期的任务进行依赖,常见 天任务依赖小时任务、 小时任务依赖分钟任务 。那么如何通过大数据开发套件开发这两种场景呢?
本文将从这两个场景出发,结合调度依赖/参数/调度执行等,介绍不同周期调度依赖的最佳操作实践。
再此之前,我们先明确几个概念:
- 业务日期:业务数据产生的日期,这里指完整一天的业务数据。在大数据开发套件里任务每天能处理的最近的完整一天业务数据是昨天的数据,所以业务日期=日常调度日期-1天。
- 依赖关系:依赖关系是描述两个或多个节点/工作流之间的语义连接关系,其中上游节点/工作流的运行状态可以影响下游节点/工作流的运行状态,反之则不成立。
- 调度实例:大数据开发套件的调度系统对周期任务进行调度执行时,会先根据任务的配置进行实例化,每个实例带上具体的定时时间、状态、上下游依赖等属性。
注意:目前数加大数据开发套件每天自动调度的实例都是在昨天晚上23:30生成。
调度规则:调度任务是否能运行起来要满足的条件:
- 上游任务实例是否都运行成功。若所有上游任务实例都运行成功则触发任务进入等待时间状态。
- 任务实例定时时间是否已经到。任务实例进入等待时间状态后会check本身定时时间是否到,如果时间到了则进入等待资源状态;
- 当前调度资源是否充足。任务实例进入等待资源状态后,check当前本项目调度资源是否充足,若充足则可以运行起来。
天任务依赖小时任务
业务场景
系统需求统计截止到每小时的业务数据增量,然后在最后一个小时的数据汇总完成后需要一个任务进行一整天的汇总 。
需求分析
1)每个小时的增量,即每整点起任务统计上个小时时间段的数据量 。需要配置一个每天每整点调度一次的任务,每天最后一个小时的数据是在第二天第一个实例进行统计 。
2)最后的汇总任务为每天执行一次,且必须是在每天最后一个小时的数据统计完成之后才能执行,那么需要配置一个天任务,依赖小时任务的第一个实例 。
分析得出的调度形态如下图:
但是,真正如上图调度任务定义那样配置调度依赖后,调度任务实例并没有得到上图的效果,而是如下图:
上图中,天任务必须等小时任务当天其他所有实例也执行完成才能执行,而需求是天任务只需依赖小时任务第一个实例,此效果明显不能满足需求 。
要达到该场景需求,此时就需要结合任务“跨周期依赖”进行配置,可以将小时任务“跨周期依赖”属性配置成“自依赖”,然后天任务配置定时时间为零点整,且依赖属性配置依赖小时任务 。
分析得出的最终方案调度形态如下图:
此时,小时任务的实例为串行执行,第一个实例能执行成功,可保证它前面(昨天)的实例都已经执行成功,因此天任务可以只需要依赖第一个实例 。
配置实践
小时任务的调度配置如下图:
天任务的调度配置如下图:
参数配置:小时任务每整点实例处理前一小时的数据,如可以用$[yyyy-mm-dd-hh24-1/24],天任务 若时间格式为yyyymmdd,用${bdp.system.bizdate};若时间格式为yyyy-mm-dd,用自定义参数$[yyyy-mm-dd-1],具体视详细设计而定 。参数配置如下图所示:
测试/补数据/自动调度
测试和补数据:都是手动生成的调度实例,选择的是业务日期 。
如选择业务日期为 2017-01-10:
- 天任务实例的定时时间是 2017-01-11 00:00:00;
- 小时实例的定时时间是 2017-01-11 00:00:00 至 2017-01-11 23:00:00;
- ${bdp.system.bizdate} 赋值结果为 20170110(实例定时间年月日减1天);
- $[yyyy-mm-dd-hh24-1/24] 赋值结果为 2017-01-10-23 至 2017-01-11-22(实例定时间年月日时减1小时)。
自动调度:调度系统自动生成的实例,每天的实例定时时间都是当天,如“需求分析”中的最终方案效果图 。
小时任务依赖分钟任务
业务场景
已经有任务每 30 分钟进行一次同步,将前 30 分钟的系统数据增量导入到 MaxCompute,任务定时为每天的每个整点和整点 30 分运行 。现在需要配置一个小时任务,每 6 个小时进行一次统计,即每天分别统计 0 点到 6 点之间、6 点到 12 点之间、12 点到 18 点之间、18 点到明天 0 点整之间的数据 。
需求分析
1) 分钟任务:
- 00:00 实例同步的是昨天最后 30 分钟的数据,产出的表分区如“昨天日期年-月-日-23:30”;
- 00:30 实例同步的是今天 00:00-00:30 之间的数据,产出的分区如“今天日期年-月-日-00:00”;
- 01:00 实例同步到是今天 00:30-01:00 之间的数据,产出的分区如“今天日期年-月-日-00:30”;
- 以此类推, 23:30 实例同步的是今天 23:00-23:30 之间的数据,产出的分区如:“今天日期年-月-日-23:00”
2)小时任务:
- 每 6 个小时进行一次统计,则一天调度 4 次;
- 统计 0 点到 6 点之间的数据,则依赖分钟任务当天的 00:30—6:00 共 12 个实例;
- 统计 6 点到 12 点之间的数据,则依赖分钟任务当天的 6:30—12:00 共 12 个实例;
- 统计 12 点到 18 点之间的数据,则依赖分钟任务当天的 12:30—18:00 共 12 个实例;
- 统计 18 点到第二天 0 点之间的数据,则依赖分钟任务当天的 18:30—23:30 以及第二天 00:00 共 12 个实例 。
分析得出的调度形态如下图:
但是,真正如上图调度任务定义那样配置调度依赖后,调度任务实例并没有得到上图的效果,而是如下图:
如上图,10 日 18 点到 11 日 0 点之间的数据,11 日小时任务 0 点整点实例只依赖了分钟任务 11 日 0 点整实例,不能确保分钟任务 10 日 18:30 至 23:30 的实例是否执行成功 。
要达到该场景需求,此时就需要结合任务“跨周期依赖”进行配置,可以将分钟任务“跨周期依赖”属性配置成“自依赖”,然后小时任务依赖属性配置依赖小时任务 。
分析得出的最终方案调度形态如下图:
此时,分钟任务的实例为串行,每个实例能执行成功,可保证它前面(或昨天)的实例都已经执行成功,因此小时任务每个实例可以只需要依赖分钟任务定时时间离它最近(小于等于)的一个实例 。
配置实践
分钟任务的调度配置如下图:
小时任务调度配置如下图:
参数配置:分钟任务每个实例处理前面30分钟数据产出的分区可以用参数如 $[yyyy-mm-dd-hh24:mi-30/24/60] , 具体视详细设计而定 。配置类似下图:
测试/补数据/自动调度
测试和补数据:都是手动生成的调度实例,选择的是业务日期。如选择业务日期为 2017-01-10:
- 分钟任务实例的定时时间是 2017-01-11 00:00:00 至 2017-01-11 23:30:00,共 48 个实例;
- 小时实例的定时时间是 2017-01-11 00:00:00、06:00:00、12:00:00、18:00:00 共 4 个实例;
- $[yyyy-mm-dd-hh24:mi-30/24/60] 赋值结果为 2017-01-10-23:30 至 2017-01-11-23:00(实例定时间年月日时分减 30 分钟)。
自动调度:调度系统自动生成的实例,每天都实例定时时间都是当天,如“需求分析”中的最终方案效果图 。
总结
- 长周期任务依赖短周期任务时,如果短周期有自依赖:当天的调度实例中,长周期任务的每个实例只依赖短周期实例中定时时间与它最近(且小于)的一个实例 。
- 长周期任务(小时)依赖短周期任务(分钟)时,如果短周期无自依赖:当天的调度实例中,长周期任务的每个实例会依赖定时时间小于等于且没被本任务其他实例依赖的短周期实例;天/周/月依赖小时/分钟任务例外,因为天任务实例会依赖所有小时/分钟任务 。
- 调度周期和调度时间参数配合使用,最终调度参数替换的值取决于每次调度的实例定时时间,而调度上看到的 业务日期=实例定时时间年月日减1天 。