2. 核心概念:DAG(有向无环图)在调度中的角色、节点与边的抽象、调度状态机模型

在分布式任务调度系统中,DAG(Directed Acyclic Graph,有向无环图) 是描述任务依赖关系的核心数学模型。它决定了任务执行的顺序、并行度以及容错边界。理解 DAG 的抽象与状态机模型,是定义调度边界接口契约的前提。

2.1 DAG 在调度中的角色

DAG 在调度系统中扮演三个关键角色:

  • 依赖编排:通过有向边明确任务间的“前驱-后继”关系,确保任务按拓扑顺序执行。
  • 并行边界:无直接或间接依赖关系的节点可以并行调度,DAG 的宽度决定了系统的最大并行度。
  • 状态聚合:DAG 的整体状态由所有节点的状态聚合而成,是调度器判断是否触发下游动作的依据。
关键设计原则:调度器不应感知任务内部逻辑,只通过 DAG 结构驱动状态流转。DAG 是调度器的“唯一真相源”。

2.2 节点与边的抽象

在 GoDAG 调度框架中,节点和边被抽象为以下核心数据结构:

抽象元素 Go 类型示例 关键字段 调度语义
Node(节点) type Node struct ID, Status, RetryCount, MaxRetry 代表一个可执行的任务单元,包含执行状态与重试策略。
Edge(边) type Edge struct FromID, ToID, Condition 代表依赖关系,Condition 可定义条件依赖(如仅当前驱成功时才触发)。
DAG(图) type DAG struct Nodes, Edges, EntryNodes 持有所有节点和边的集合,提供拓扑排序与环检测方法。
接口契约要点:Node 的 Status 字段必须与调度状态机模型严格对齐;Edge 的 Condition 应支持扩展,例如“前驱成功”、“前驱失败”或“前驱完成(无论成败)”。

2.3 调度状态机模型

每个节点在调度生命周期中经历以下状态转换。该状态机是调度器与执行器之间的通信协议基础。

节点调度状态机模型 PENDING RUNNING SUCCESS FAILED RETRYING SKIPPED 调度 完成 失败 重试 重试上限未达 条件不满足 状态说明 PENDING: 等待调度 RUNNING: 执行中 SUCCESS: 成功终止 FAILED: 失败终止 RETRYING: 重试中 SKIPPED: 跳过
状态机边界约束:FAILED 状态是最终态,不允许自动转换到 RETRYING。重试逻辑必须在 RUNNING 状态内由执行器自行处理,或由调度器在 RUNNING→FAILED 之前插入 RETRYING 中间态。接口契约必须明确区分“节点失败”与“DAG 失败”。

2.4 状态转换的接口契约

调度器与执行器之间通过以下标准接口交互,驱动状态机流转:

// Scheduler 调度器接口
type Scheduler interface {
    // Submit 提交一个节点到调度队列,返回当前状态
    Submit(nodeID string) (Status, error)

    // Cancel 取消一个节点的执行
    Cancel(nodeID string) error

    // GetStatus 查询节点当前状态
    GetStatus(nodeID string) (Status, error)
}

// Executor 执行器接口
type Executor interface {
    // Execute 执行一个节点,返回执行结果状态
    Execute(ctx context.Context, node *Node) (Status, error)

    // OnStatusChange 状态变更回调,通知调度器
    OnStatusChange(nodeID string, oldStatus, newStatus Status)
}
契约校验点:Execute 返回的状态必须属于 {SUCCESS, FAILED};OnStatusChange 不允许跳过中间态(如直接从 PENDING 跳转到 SUCCESS)。调度器应拒绝非法状态跃迁。

2.5 小结