1.策略设计
1.1 场景
数据平台(Greenplum)批处理任务调度。
1.2 任务调度策略影响因素
需求确认对后续的技术选型至关重要。技术选型和需求之间的关系是密切相互关联的。在项目开发或解决问题时,首先需要明确需求,即确定项目或问题的目标、功能、用户需求等。然后根据需求,选择最合适的技术来实现目标。(标“★”为重要因素)
-
提供依赖关系视图(★)
-
作业类型
-
任务编排与调度需求
1)按计划时间和周期执行(★)
2)按任务依赖关系执行(任务内部task间依赖和任务间依赖)(★)
3)按任务的优先级和重要性执行(★)
4)按系统的负载情况和资源利用率执行(可配合资源调度系统实现)
5)通过事件触发(★)
数据到达、http信号触发、任务失败触发等。
6)批处理调度
按照一定数量或一定时间间隔将任务打包成批次进行处理,可以减少任务执行开销,提高执行效率。 -
任务监控与管理需求
1)任务状态监控(★)- 追踪并提供入口查询任务状态,包括已完成、运行中、失败。
2)任务进度监控(★)
- 甘特图
3)任务日志记录(★)
- 任务状态、开始时间、完成时间、执行的任务名、错误原因等。
4)报警机制(★)
5)重试机制(★)- 固定重试次数:在任务执行失败时,固定重试一定次数,直到任务执行成功或达到最大重试次数。需要注意的是,固定重试次数可能会导致任务重复执行或任务执行超时等问题。
- 前置依赖未完成:判断前置任务状态未完成时,失败任务,并按一定时间间隔重调任务,直到成功或因其他原因导致失败。
- 递增重试间隔:在任务执行失败时,按照一定的规律递增重试间隔,即每次重试时等待的时间逐渐增加。这种重调机制能够避免任务重复执行和任务执行超时等问题。
- 多种方式重试:在任务执行失败时,采用多种方式进行重试,比如可以在不同时间、不同集群、不同节点上重试,或者重新启动整个任务流程等,以提高任务执行成功的概率。
- 弹性调度:在任务执行失败时,根据任务的依赖关系和集群负载情况,自动调整任务执行的时间、节点、资源等,以保证任务能够执行成功。
- 手动触发重试:在任务执行失败时,由管理员或操作员手动触发重试,以及时处理任务执行异常情况。
- 追踪并提供入口查询任务状态,包括已完成、运行中、失败。
-
分布式任务调度需求
-
多数据源支持需求
2.调度平台原理
调度平台核心组件为Scheduler(负责计划任务,通常配合队列机制使用)、DataBase(负责存储相关任务、任务状态、变量、连接信息等元数据)、Worker(负责按照Scher的计划执行任务)、Webserver或者其他客户端(用户的入口)。通过这些组件,将任务间的依赖关系、计划时间等“自然语言”映射为“程序语言”,并实现任务状态追踪,进而实现任务的监控和管理。设计理论是通过一套组件,将任务、流程、规则这三个“业务对象”映射到程序中。下文以AirFlow举例说明:
- Airflow的组件框架:
- scheduler,它处理触发计划的工作流,并将任务提交给executor运行。
- executor,处理正在运行的任务。在默认的 Airflow 安装中,它运行在scheduler中,但大多数适合生产的executor实际上将任务执行推送给workers。
- webserver,它提供了一个方便的用户界面来检查、触发和调试 DAG 和任务的行为。
- DAG Directory,由scheduler和executor(以及executor所有的worker)读取
- Metadata Database,供scheduler, executor和webserver用来存储状态
- Airflow任务执行流程:
初始状态有两个进程运行:
- SchedulerProcess:处理tasks并使用CeleryExcutor运行
- WorkerProcess:观察队列等待新的tasks出现
两个抽象的数据库,使用celery:
- QueueBroker
- ResultBackend
运行task过程中,创建了两个进程:
- LocalTaskJobProcess:他的逻辑由LocalTaskJob描述,同时监控RawTaskProcess的状态,新的进程将由Taskrunner启动。
- RowTaskProcess:它用来处理用户实际的代码,比如用户执行的一行shell。
[1] SchedulerProcess处理任务,当它发现需要完成的任务时,将其发送到QueueBroker。
[2] SchedulerProcess也会周期性的查询ResultBackend以获取任务的状态。
[3] QueueBroker当它意识到有新任务产生时,会将有关它的信息发送到 WorkerProcess
[4] WorkerProcess将单个任务分配给一个WorkerChildProcess。
[5] WorkerChildProcess执行适当的任务处理功能 - 关键方法:execute_command()。并创建个新的进程 - LocalTaskJobProcess。
[6] LocalTaskJobProcess 逻辑由LocalTaskJob类描述。它使用 TaskRunner 启动的新进程。
[7] RowTaskProcess 执行用户实际的代码,这一步是最底层真正执行task的操作
[8][9] Process RawTaskProcess和LocalTaskJobProcess在完成task后停止。
[10] WorkerChildProcess通知主进程-WorkerProcess任务结束以及后续任务的可用性。
[11] WorkerProcess将状态信息保存在ResultBackend 中。
[12] 当SchedulerProcess再次询问ResultBackend状态时,将会获取到任务状态的信息。
- 日志监控框架与状态追踪:
logging配置参考:Logging for Tasks — Airflow Documentation
DAG级别状态:
状态 | 说明 |
---|---|
QUEUED | 已排队 |
SUCCESS | 成功 |
RUNNING | 成功 |
FAILED | 失败 |
TASK级别状态:
状态 | 说明 |
---|---|
NONE | 无 |
REMOVED | 已移除 |
RUNNING | 运行中 |
SCHEDULED | 已调度 |
QUEUED | 已排队 |
SHUTDOWN | 关闭 |
UP_FOR_RETRY | 等待重试 |
UP_FOR_RESCHEDULE | 上游失败 |
SKIPPED | 已跳过 |
SENSING | - |
参考文章:
Airflow 核心原理分析:Airflow 核心原理分析
Architecture Overview:Architecture Documentation