0%

关于任务调度/分发系统的设计总结(0)

以数据采集系统为例,简单记录一下如何设计一个相对可用的任务调度/分发系统

目标

我们设计的目标是一个数据采集系统,有以下目标

  • 用户可以提交任务。(new job)
  • 用户可以按照特定的规则配置一类Job的运行规则(JobRule),该执行规则结合执行结果,可在动态生成子任务,子任务同样有自己的JobRule
  • 任务是树状的,即存在parentJob与children之间的关系,parent可在运行过程中,根据远端响应以及任务的配置,动态的生成不定数量的子任务,该过程是可嵌套循环下去的
  • 任务存在状态 Pending、Running、Finished、Error、Warning等
  • 任务有输出

初步流程设计

几种角色

  • User: 提交初始任务
  • Dispatcher: 调度任务到相关队列
  • Executor: 实际执行任务
  1. User将任务提交到Waiting Pool
  2. Dispatcher按照一定的规则,从Waiting Pool中获取新增加的Job,将其分配到JobQueue中
  3. Executor从对应的JobQueue中获取新的任务(该Job将不会从队列中被移除,仅隐藏),创建JobSession。Session代表一个任务的一次执行。
  4. Executor尝试执行任务。
    1. 如果任务成功执行,则提交Job的执行结果。报告任务Session成功状态,并按照JobRule判断是否需要创建子任务,完成后将从JobQueue中移除该Job
    2. 如果失败,则LocalRetryCount++, 如果LocalRetryCount超过了本地可重试的上限,则标记该Session失败。等待该任务从JobQueue中自动恢复

mermaid图

调度流程

graph TD
    A[User] -->|Submit New Job To| B[Waiting Pool]
    B --> |Fetched By Dispatcher|C[JobDispatcher]
    C-->|Dispatch Job|D[JobQueue]
    D-->|Fetched By Executor| E[JobExecutor]
    E-->|Dynamic Generated Jobs|B

Executor执行流程

graph TD
    A[Job]-->|SetJobRunSession|B[JobWithSession]
    B-->|TryRunJobWithSession|C{ExecutionResult?}
    C-->|Ok|D[StoreData]
    D-->|TryGenerateChild|E[Waiting Pool]
    C-->|Error or Exception|F{ExceedLocalRetryCount}
    F-->|Yes|G[ReportSessionErrorToServer]
    F-->|No|B