调度属性配置
概述
什么是调度
在搜索引擎中是这样解释的:“对资源进行合理的分配,以使系统中的用户得以正常良好的通信。这种分配的方法或者策略,即为调度算法或者调度技术”
在离线开发中,调度系统的作用与之类似。在典型的批处理场景中,任务都是周期性的运行(例如每天运行一次),且不同的任务之间会存在上下游依赖关系,例如数据同步任务会首先运行,之后才运行SQL处理任务。在这一过程中,周期性、任务的上下游依赖关系就是「调度」的基本概念。
任务与实例的关系
任务与实例是一对多的关系,在「数据开发」模块中配置的SQL任务、同步任务,其中包含代码、配置信息等,这是一个任务(Job),一个任务每运行一次,被称作一个实例(Instance)。任务是固定的一个配置,将一个任务运行多次,每次的结果、数据产出都不一样,在概念上进行区分是很有必要的。在本文的描述中,「任务」和「实例」可能会混用,读者需结合上下文理解其实际含义
调度系统的职责
调度系统的职责可以归结为两方面:“生成实例”和“按计划运行实例”,具体如下
一、生成实例
当任务提交到调度系统后,系统会根据调度配置来生成实例,默认是在计划时间的前一天的22:00生成第二天需要执行的实例。实例生成规则中会进行详细介绍。
二、按计划运行实例
每天按计划运行实例时,调度系统判断一个实例是否可以运行,需要满足两个条件:
- 任务是否到达了计划时间
- 上游任务是否全部成功
若不能满足以上两个条件,则任务会处于等待提交状态。若满足了以上两个条件,调度系统会将任务“提交”至计算引擎(任务进度等待运行状态),任务还需要获得集群的计算资源 ,集群资源由计算集群分配,用户可以通过配置「资源组」、「环境参数」或在控制台杀死其他任务,来影响任务获取的计算资源。实例的状态转换具体可查看实例的生命周期
上文提到了,其中一个条件为「上游任务是否全局成功」,当调度系统去寻找上游实例时,基本原则是:
- 第一条:实例在寻找上游依赖时,若上游任务存在当天执行的实例则会将当天执行的实例作为上游依赖(若是未来时间,也会将当天执行的实例作为上游依赖),没有则找最近的上游实例。
- 第二条:第一条原则在上游任务或当前任务为小时任务或分钟任务(cron和自定义调度周期需每天>1个实例)时不生效,当上游任务或当前任务为小时任务或分钟任务时(cron和自定义调度周期需每天>1个实例),实例在寻找上游依赖时,会去寻找一个与其计划时间相等,或之前最近的实例,不会去默认寻找当天的实例。
调度属性
在「数据开发」模块,任意打开一个任务,可在其右侧的「调度属性」面板中,进行“调度属性”的配置。如下图所示,配置内容主要包括实例生成方式、调度状态、出错重试、生效日期、调度周期、资源组、超时时间等。
实例生成方式
配置
离线开发的调度系统会给任务自动生成实例。可在调度属性中指定实例在T+1生成或即时生成。指定实例生成方式为「立即生成」时,系统会立即生成实例,可立即在运维中心中查看生成的实例;指定实例生成方式为「T+1生成」时,系统会在22:00生成第二天运行的实例,生成后也可在运维中心中查看生成的实例。实例生成方式配置功能,如下图所示
立即生成实例
该功能仅专业版、旗舰版支持
当任务计划时间在提交发布时间的15分钟之后(包含15分钟)(例如提交时间是18:00,定时运行时间是18:16),会正常生成实例运行任务;
当任务计划时间距离提交时间不足15分钟(例如提交时间是:18:00,定时运行时间是18:05),则任务将会无法提交。这样是为了给实例立即生成预留充足的时间。
当立即生成实例生效后,已生成的任务实例会被删除并替换成实时生成的实例,对应实例在运维中心的依赖视图也会进行变化。
如上图所示,修改任务B的调度周期为天任务并将实例生成方式选择立即生成实例。在T1所示时间点提交后,原本已生成的,用于T1时间点之后任务运行的B任务小时实例会被删除,并且产生1个新的天实例,即提交前,B为小时任务,提交后为天任务。
在T1时间提交后,B任务的下游任务C会依赖到新产生的天实例上。
如果B的调度配置中勾选了依赖上一周期,且依赖项选择为「自依赖」,则变更后,新产生的第一个天节点实例会跨周期依赖上个运行周期里的小时实例。
T+1生成实例
选中「T+1生成实例」,提交后离线开发在每天22:00统一生成第二天所有需要的任务实例,基于以上设计,任务开发时需要注意任务的提交时间,这里以一个天周期调度任务A为例:
任务A基本信息:调度周期:1天;具体调度时间:8:00;
- 若在1月1日21:00提交A任务(时间轴上侧),离线开发会在当天22:00产生A任务的实例,并会在1月2日8:00第一次运行
- 若在1月1日23:00提交A任务(时间轴下侧),由于离线开发已经在22:00产生了1月2日的所有实例,A任务在1月2日将不会运行。A任务的实例将会在1月2日22:00产生,并在1月3日第一次运行
系统默认会在22:00生成第二天运行的实例,可以通过调整batch.job.graph.build.cron来更改实例生成时间,通过下图两个步骤进行修改
1、打开EM找到engine服务
2、在配置信息中找到batch.job.graph.build.cron修改时间
调度状态
如果需要让某个任务停止运行一段时间,可以在「任务开发」模块打开某任务,在右侧「调度依赖」面板中勾选「冻结」,表示此任务进入冻结状态,无需提交立即生效。
- 处于冻结状态的任务,其周期实例依然会生成,但不会运行
- 对于存在依赖关系的多个任务,如果将上游任务A冻结,则下游任务B也会进入「冻结」状态,B任务的实例也会产生,但不会运行,在B任务的执行日志中会打印出是由于A任务被冻结才没有运行的
- 冻结是立即生效的,冻结状态的任务,生成的实例不会立即进入冻结状态,会首先进入等待提交状态,到达计划时间后,无论上游任务的状态怎样,会立即进入冻结状态,按此逻辑,若任务实例的计划时间还未到达,任务解冻后可以正常运行
- 已经进入冻结状态的实例无法解冻,若需要这些实例执行,必须先对任务解冻,解冻后再对实例进行「重跑」
对冻结状态的任务执行补数据,补数据实例会正常运行
出错重试
勾选出错重试,当本任务运行失败时,会进行自动重试,每次间隔2分钟,可配置重试1次至5次,默认重试3次。
建议对重点任务配置重试,例如如下几种场景:
- 数据量较大的同步任务,或运行时间较长的同步任务
- 某些重要性较高的任务
- 某些资源消耗比较大的任务
生效日期
指当前调度任务的调度生效日期范围,默认为100年,若有特殊需要可以修改此时间范围,超出生效日期后,此调度任务的实例不会再生成。
调度周期
可配置「调度周期」为天、周、月、小时、分钟、cron表达式及自定义调度周期等方式。
调度周期 | 起调时间配置 |
---|---|
日 | 天调度任务,即每天自动运行一次。新建周期任务时,默认的时间周期为每天0点运行一次,可根据需要自行指定运行时间点,配置"具体时间": - 小时:单选下拉列表,00-23,默认选中00 - 分钟:单选下拉列表,00-59,默认选中00 |
周 | 周调度任务,即每周的特定几天里每天在特定时间点自动运行一次,需配置 选择时间 和 具体时间 - 选择时间:复选下拉列表{星期一;星期二;……星期日},可复选,默认选中 星期一 - 具体时间:同 调度周期-日 相同; |
月 | 月调度任务,即每月指定的特定几天里每天在特定时间点自动运行一次,需配置 选择时间 和 具体时间 - 选择时间:复选下拉列表{每月最后一天;每月1号;每月2号;……每月31号},可复选,默认选中 星期一 - 具体时间:同 调度周期-日 相同; |
小时 | 小时调度任务,即每天指定的时间段内按N*1小时的时间间隔运行一次,比如每天1点到4点的时间段内,每1小时运行一次。当调度周期切换到非天级调度时,节点起调时间将不可选,需配置 开始时间 、 结束时间 和 间隔时间 - 开始时间、结束时间:同 调度周期-日 类似,小时可选择00-23,分钟不可选,开始时间的分钟为0,结束时间的分钟为59; - 间隔时间:单选下拉列表{1小时;2小时……23小时},默认选中1小时; - 开始时间,应早于结束时间 ; |
分钟 | 分钟调度任务,即每天指定的时间段内按N*指定分钟的时间间隔运行一次,目前能支持的最短时间间隔为每5分钟运行一次,当调度周期切换到非天级调度,节点起调时间将不可选,需配置 开始时间 、 结束时间 和 间隔时间 - 开始时间、结束时间:同 调度周期-小时 相同; - 间隔时间:单选下拉列表{5分钟;10分钟;……55分钟},默认选中5分钟; - 开始时间,应早于结束时间 |
Cron表达式 | 填写Cron表达式 |
自定义调度周期 | 选择在控制台上传的自定义调度周期 |
- 按照小时周期调度时,时间周期按左闭右闭原则计算,比如配置为从0点到2:59点的时间段内,每隔1个小时运行一次,表明时间区间为[00:00,02:59],间隔为1小时,调度系统将会每天生成3个实例,分别在0:00/1:00/2:00运行。
- 离线开发支持的最小调度间隔为5分钟,不支持更短的调度周期,若存在此种场景,可考虑实时计算等其他解决方案
- 具体时间并不表示任务的实际开始时间,系统可能会因为上游任务延迟、集群资源紧张等原因造成延迟执行
Cron表达式
该功能仅旗舰版支持
Cron表达式是一个具有时间含义的字符串,字符串以5~6个空格隔开,离线仅支持6个域,格式为X X X X X X
。其中X
是一个域的占位符。代表年份的域离线获取的是生效日期的年份。单个域有多个取值时,使用半角逗号,
隔开取值。每个域可以是确定的取值,也可以是具有逻辑意义的特殊字符。每个域最多支持一个前导零。
说明 如指定每天上午8:15执行任务,Cron表达式可指定为0 15 8 ? * *
或0 15 08 ? * *
,而不能指定为0 15 008 ? * *
。
域取值
下表为Cron表达式中六个域能够取的值以及支持的特殊字符。
域 | 是否必需 | 取值范围 | 特殊字符 |
---|---|---|---|
秒 | 是 | [0, 59] | * , - / |
分钟 | 是 | [0, 59] | * , - / |
小时 | 是 | [0, 23] | * , - / |
日期 | 是 | [1, 31] | * , - / ? L W |
月份 | 是 | [1, 12]或[JAN, DEC] | * , - / |
星期 | 是 | [1, 7]或[MON, SUN]。若您使用[1, 7]表达方式,1代表星期一,7代表星期日。 | * , - / ? L # |
特殊字符
Cron表达式中的每个域都支持一定数量的特殊字符,每个特殊字符有其特殊含义。
特殊字符 | 含义 | 示例 |
---|---|---|
* | 所有可能的值。 | 在月域中,表示每个月;在星期域中,表示星期的每一天。 |
, | 列出枚举值。 | 在分钟域中,5,20表示分别在5分钟和20分钟触发一次。 |
- | 范围。 | 在分钟域中,5-20表示从5分钟到20分钟之间每隔一分钟触发一次。 |
/ | 指定数值的增量。 | 在分钟域中,0/15表示从第0分钟开始,每15分钟。在分钟域中3/20表示从第3分钟开始,每20分钟。 |
? | 不指定值,仅日期和星期域支持该字符。 | 当日期或星期域其中之一被指定了值以后,为了避免冲突,需要将另一个域的值设为?。 |
L | 单词Last的首字母,表示最后一天,仅日期和星期域支持该字符。 | 在日期域中,L表示某个月的最后一天。在星期域中,L表示一个星期的最后一天,也就是星期日(SUN)。如果在L前有具体的内容,例如,在星期域中的6L表示这个月的最后一个星期六。 |
W | 除周末以外的有效工作日,在离指定日期的最近的有效工作日触发事件。W字符寻找最近有效工作日时不会跨过当前月份,连用字符LW时表示为指定月份的最后一个工作日。 | 在日期域中5W,如果5日是星期六,则将在最近的工作日星期五,即4日触发。如果5日是星期天,则将在最近的工作日星期一,即6日触发;如果5日在星期一到星期五中的一天,则就在5日触发。 |
# | 确定每个月第几个星期几,仅星期域支持该字符。 | 在星期域中,4#2表示某月的第二个星期四。 |
取值示例
以下为Cron表达式的取值示例。
示例 | 说明 |
---|---|
0 0 10,14,16 * * ? | 每天上午10:00点、下午14:00以及下午16:00执行任务 |
0 0/30 9-17 * * ? | 每天上午09:00到下午17:00时间段内每隔半小时执行任务 |
0 14 * ? | 每天下午14:00到下午14:59时间段内每隔1分钟执行任务 |
0 0-5 14 * * ? | 每天下午14:00到下午14:05时间段内每隔1分钟执行任务 |
0 0/5 14 * * ? | 每天下午14:00到下午14:55时间段内每隔5分钟执行任务 |
0 0/5 14,18 * * ? | 每天下午14:00到下午14:55、下午18:00到下午18:55时间段内每隔5分钟执行任务 |
0 15 10 L * ? | 每月最后一日上午10:15执行任务 |
0 15 10 ? * 6L | 每月最后一个星期六上午10:15执行任务 |
0 15 10 ? * 6#3 | 每月第三个星期六上午10:15执行任务 |
0 10,44 14 ? 3 WED | 每年3月的每个星期三下午14:10和14:44执行任务 |
离线开发目前仅支持6位表达式,因为离线开发不存在秒级别的调度任务
离线开发目前仅支持6位表达式,因为离线开发不存在秒级别的调度任务
自定义调度周期
该功能仅专业版、旗舰版支持
当调度周期无规律且复杂时,用户可使用自定义调度周期,例如在金融客户的使用场景中,可能存在计划日期是国内外的金融交易日期,交易日期无法用cron表达式等方式表示,因此可使用自定义调度日期。
自定义调度周期配置
控制台管理员可在「控制台->全局配置->自定义调度周期」中点击「添加按钮」上传自定义调度日期,如图所示
按要求上传csv格式文件并填写名称,系统将解析出上传的自定义调度日期。文件模版中标明了日期上传要求,如下图
按要求填写自定义调度周期,如下图
上传文件,弹窗展示如下图日历,可预览文件中配置的自定义调度日期
在弹窗中展示最后一次调度日期,若最后一次调度日期与当前日期时间间隔小于等于十天,则会在列表中变红提示。
点击确认后,列表末尾生成新的记录
点击「查看」按钮,可以查看自定义调度配置信息和任务使用情况,如图
点击「编辑」按钮,可以对自定义调度周期进行下载和重新上传
对自定义调度周期进行删除时,需要确认没有任务应用
自定义调度周期使用
已添加的调度周期在全平台范围内生效,在任一任务的「调度依赖->调度属性」选中「自定义调度周期」,会在下方展示自定义调度周期选择框,如图所示
自定义调度周期的选择范围是所有在控制台配置的自定义调度周期,选中自定义调度日期后,可点击右侧的「预览」按钮,可以查看自定义调度周期的生效范围,如图所示
当自定义调度周期上传模版是精确到日期时,选择该自定义调度周期,可在调度配置处设置调度时分,如下图所示
资源组
默认使用在「项目管理」中指定的默认资源组,针对任一个资源组,可以点击「查看水位」查看今日和昨日的不同时段的资源负载情况,用于资源组选择的参考。
关于资源组的介绍和详细配置请参考资源组管理。
超时时间
任务配置超时时间后,运行时间超过超时时间后会强制杀死,对周期任务、临时运行、手动任务生效。目的是当一个任务长时间处于「运行中」状态时,会导致资源的占用,通过设置“超时时间”,可以及时释放资源。
自动跳过
由于小时/分钟任务的调度频率很高,且偶尔会存在执行时间过长的情况,为节约计算资源,让任务尽快「追赶」上当前时间,离线开发支持对小时/分钟任务配置自动跳过的逻辑
假设设置分钟任务的调度周期为10分钟一次,正常需要2分钟运行完成,且分钟任务处理的是当天全天的数据,且设置了自依赖模式,在2020-05-03,任务的计划时间点分别为:
- 2020-05-03 23:10:00 --集群发生故障,任务在23:11分启动运行,但直到23:35才运行结束
- 2020-05-03 23:20:00 --不运行实例,直接将其状态置为「自动取消」
- 2020-05-03 23:30:00 --不运行实例,直接将其状态置为「自动取消」
- 2020-05-03 23:40:00 --运行23:40的实例
- 2020-05-03 23:50:00 --无论是否跳过,一天中的最后一个实例都会运行
- 2020-05-04 00:00:00
如上文所述,在小时、分钟任务中,如果勾选了自动跳过,则离线开发可以自动跳过已经「过期」的实例,直接运行最新的一个,即可实现最新数据的产出,当然这对任务代码、自依赖模式也有要求
自动跳过只会跳过一天中间的实例,某一天最后一个实例(上例中的23:50的实例)不会跳过,以保障当天最后一个实例产出当天全天的数据
其他
- 任务被删除
如果此任务被其他任务依赖(是其他任务的上游任务),则此任务不能被删除,您需要先解除依赖关系再进行删除, 任务删除后,已生成的任务实例不会被删除,但会运行失败
- 想在每月的最后一天计算当月数据怎么办
离线开发在配置任务调度时,配置的都是计划时间,通常的每月最后一天计算当月数据,都是指的是每月1日凌晨计算上个月整月数据,建议计划时间选择每月的1日运行即可