2. Airflow基础回顾
在进入数据依赖与补数回填的实战之前,我们必须先把 Airflow 的“骨架”重新梳理一遍。很多同学在写 DAG 时觉得“能跑就行”,但一旦遇到依赖错乱、任务卡住、回填失败,就会发现自己对 Scheduler、Executor、Metadata Database 之间的协作关系并不清楚。本节将围绕 DAG、Task、Operator、Scheduler、Executor、Metadata Database 六大核心组件,讲清它们各自的职责与协同机制,为后续的依赖管理与补数回填打下坚实基础。
一、核心组件职责拆解
Airflow 本质上是一个“编排调度系统”,它并不负责计算本身,而是负责决定“什么任务、在什么时间、以什么顺序、由谁执行”。理解这一点,才能理解各组件的分工。
- DAG(有向无环图):描述任务之间的依赖关系与调度周期,是逻辑层面的“工作流定义”。DAG 本身不执行任何计算,它只是一份声明。
- Task(任务):DAG 中的一个节点,代表一个具体的执行单元。Task 是 DAG 的实例化节点,携带依赖关系与重试策略。
- Operator(算子):Task 的“模板”,决定这个任务具体做什么,例如
BashOperator、PythonOperator、SQLExecuteQueryOperator。Operator 是能力的封装,Task 是 Operator 的运行时实例。 - Scheduler(调度器):Airflow 的“大脑”,负责解析 DAG 文件、判断依赖是否满足、生成 DagRun 与 TaskInstance,并把可执行任务推给 Executor。
- Executor(执行器):负责真正“跑任务”的组件,决定任务在本地进程、Celery 队列还是 Kubernetes Pod 中执行。
- Metadata Database(元数据库):Airflow 的“记忆中枢”,存储 DAG 结构、任务状态、调度历史、变量、连接等所有状态信息。Scheduler 与 Executor 都依赖它来协调。
二、运行机制:一次调度的完整链路
理解组件之后,我们来看一次典型的调度是如何发生的。假设你有一个每天凌晨 2 点运行的 DAG,包含 extract → transform → load 三个任务。
- Scheduler 周期性扫描 DAG 目录,解析 DAG 文件,将 DAG 结构与调度周期写入 Metadata Database。
- 到达调度时间点后,Scheduler 在元数据库中创建一条 DagRun 记录,表示“本次调度已触发”。
- Scheduler 根据依赖关系,为每个 Task 创建 TaskInstance,并判断其依赖是否满足。
- 依赖满足的 TaskInstance 被放入 Executor 的执行队列。
- Executor 拉起 Worker(或本地进程)执行 Operator 逻辑,执行结果与日志状态回写 Metadata Database。
- 下游任务看到上游状态变为 success 后,被 Scheduler 解锁并继续执行,直到整个 DagRun 完成。
可以看到,Metadata Database 是整个链路的“唯一真相来源”。Scheduler 不直接与 Worker 通信,而是通过数据库状态来协调。这也是为什么数据库性能会直接影响调度延迟。
三、关键概念对照清单
为了便于后续章节查阅,这里用一张表把容易混淆的概念对齐清楚。
| 概念 | 层级 | 核心作用 | 常见误区 |
|---|---|---|---|
| DAG | 逻辑定义 | 描述依赖与调度周期 | 误以为 DAG 会执行任务 |
| Task | DAG 节点 | 依赖关系中的执行单元 | 与 Operator 混为一谈 |
| Operator | 能力模板 | 定义任务具体做什么 | 认为 Operator 就是 Task |
| Scheduler | 调度中枢 | 解析、判断、触发任务 | 以为它直接执行任务 |
| Executor | 执行中枢 | 决定任务在哪里运行 | 忽略其与队列的关系 |
| Metadata DB | 状态存储 | 保存所有运行状态 | 忽视其性能瓶颈 |
四、案例与常见误区复盘
来看一个真实场景:某团队配置了 CeleryExecutor,DAG 每天运行正常,但某天开始任务大量延迟。排查后发现,Scheduler 仍在正常触发 DagRun,但 TaskInstance 长时间停留在 queued 状态。原因不是 DAG 写错,而是 Celery Worker 数量不足,任务堆积在队列中。这个案例说明:调度成功 ≠ 执行成功,Scheduler 与 Executor 是两个独立环节。
# 查看任务实例状态(示例)
airflow tasks states my_dag extract 2024-06-01
# 常见状态
# queued -> 已进入执行队列,等待 Worker
# running -> Worker 正在执行
# success -> 执行成功
# failed -> 执行失败,等待重试或人工处理
# up_for_retry -> 等待重试
误区二:忽略 Metadata Database 的重要性。数据库慢,Scheduler 解析和状态更新都会变慢,表现为“调度延迟”。
误区三:认为 Executor 只影响性能。Executor 类型决定了任务的隔离性、并发能力和失败恢复方式,直接影响补数回填策略。
回顾本节,DAG、Task、Operator 属于“定义层”,Scheduler、Executor 属于“运行层”,Metadata Database 则是贯穿两者的“状态层”。只有把这三层关系理清,后续我们讨论数据依赖、触发规则、补数回填时,才能准确判断问题出在定义、调度还是执行环节。