平台ETL DAG调度策略
2020-01-02 本文已影响0人
姜小嫌
以下策略没有考虑业务相关问题<如任务优先级等等>,只是从纯平台工具链考虑基于DAG依赖的调度策略。
1.目前etl的fetch task策略是基于任务子孙任务数和任务优先级获得task list
2.然后遍历task list 查看任务是否具备执行条件
- 集群资源校验(yarn/hdfs)<如果这里有性能瓶颈,可以抽出来做公共接口map,每10s更新一次>
- 数据是否准备好(仅mysql task具备),解决主从延迟问题
- 任务开始时间
- 任务的父任务是否都执行成功
3.每10s fetch一次task,遍历一次基于<2>的逻辑
- 我们把任务的父任务执行状态判断放到最后是想降低数据库查询成本(如果没放到最后,可以在exec_log表中维护一个依赖是否校验的状态去动态变更来减少数据库轮训查找成本)
- 我们如何避免,如 a->b->c 依赖关系,a还没完成又去校验b,b又没通过,又去校验c这种情况呢(如果此树较大,我们又是基于子孙任务数排序的话,会出现这种无谓遍历数据库的情况)。如果我们没有维护全局树及树中各任务的状态的话(成本较高,要时刻保证内存中的树与mysql表的任务状态同步)。
- 有如下两张表,直接用sql可解决之前说的问题,注:<假如任务状态status=0 为成功>
denpend <parent_id,child_id>
exec_log <task_id,status> - depend 表的父id join exec_log 表的task_id,那么depend.child_id, depend.parent_id(=exec_log.task_id), exec_log.status(父任务的状态)就出来了,group by depend.child_id ,sum(exec_log.status)=0 的depend.child_id可以跑,否则不可跑
此策略已上线,按天调度1.6w个任务,运行稳定!!!