Apache Airflow 系列教程 | 第1课:Apache Airflow 概述与架构全景
导读(Introduction)
欢迎来到 Apache Airflow 源码深度解析系列的第一课。
Apache Airflow 是当今最流行的开源工作流编排平台之一,被全球数千家企业用于构建、调度和监控数据管道。从 Airbnb 内部工具到 Apache 顶级项目,Airflow 已经成为数据工程领域的事实标准。
本课程系列的独特之处在于:我们不仅教你"如何使用" Airflow,更带你深入源码层面理解"它是如何工作的"。通过剖析真实的源代码结构,你将获得对 Airflow 内部机制的深刻理解,这将帮助你更好地调试问题、优化性能,甚至贡献代码到开源社区。
本课作为系列的开篇,将为你建立一个关于 Airflow 的全景认知——从核心概念到系统架构,从代码组织到依赖关系。这是后续所有深入学习的基础。
学习目标(Learning Objectives)
完成本课学习后,你将能够:
- 理解 Airflow 的定位与核心价值——明确它在数据工程生态中解决什么问题
- 掌握核心概念体系——DAG、Task、Operator、Scheduler、Executor 等核心术语
- 理解架构演进——从 Airflow 2.x 单体架构到 3.x 分包架构的设计思想
- 熟悉项目代码结构——了解
airflow-core、task-sdk、providers等顶层模块的职责划分 - 分析依赖关系——通过
pyproject.toml理解各包之间的关联和技术栈选择 - 搭建开发环境——了解本地开发环境配置和 Breeze 开发工具
正文内容(Main Content)
1. Airflow 是什么:工作流编排平台的定位与核心价值
1.1 问题背景
在现代数据驱动的企业中,每天有大量的数据处理任务需要按照特定的依赖关系和时间规则执行:
- 凌晨从业务数据库抽取数据到数据仓库
- 数据清洗和转换任务必须等上游抽取完成
- 机器学习模型每天重新训练
- 报表在每个工作日早上 8 点前生成
这些任务构成了复杂的工作流(Workflow),手动管理这些任务的执行顺序、失败重试、资源分配等问题非常困难。
1.2 Airflow 的解决方案
Apache Airflow 将工作流定义为代码(Workflow as Code),使用 Python 语言描述任务及其依赖关系。这带来了几个关键优势:
| 特性 | 说明 |
|---|---|
| 代码即工作流 | 用 Python 定义 DAG,享受版本控制、代码审查、测试等软件工程最佳实践 |
| 可视化监控 | Web UI 提供 DAG 运行状态、任务日志、甘特图等全方位监控 |
| 可扩展性 | 通过 Operator/Hook/Sensor 机制轻松集成任何外部系统 |
| 弹性调度 | 支持 Cron 表达式、时间间隔、数据资产触发等多种调度方式 |
| 故障恢复 | 自动重试、告警通知、手动触发回填 |
1.3 Airflow 不是什么
理解 Airflow 的边界同样重要:
- 不是数据流引擎:不像 Spark Streaming 或 Flink 处理实时数据流
- 不是数据处理框架:不直接处理大数据,而是调度其他工具(如 Spark)来处理
- 不适合超低延迟场景:调度粒度通常在秒到分钟级别
2. 核心概念速览
在深入源码之前,我们需要建立一套统一的术语体系。以下是 Airflow 中最核心的概念:
2.1 DAG(Directed Acyclic Graph,有向无环图)
DAG 是 Airflow 中最基本的组织单元,代表一个完整的工作流。"有向"意味着任务之间有明确的执行顺序;"无环"意味着不存在循环依赖。
fromairflow.sdkimportdag,task@dag(schedule="0 2 * * *",start_date=pendulum.datetime(2024,1,1))defmy_etl_pipeline():"""每天凌晨2点执行的 ETL 管道"""...2.2 Task(任务)
Task 是 DAG 中的一个执行单元,代表一个具体的工作步骤。每个 Task 都是某个 Operator 的实例。
2.3 Operator(算子)
Operator 定义了 Task 要"做什么"。Airflow 提供丰富的内置 Operator:
PythonOperator:执行 Python 函数BashOperator:执行 Shell 命令KubernetesPodOperator:在 K8s Pod 中运行任务
2.4 Scheduler(调度器)
Scheduler 是 Airflow 的"大脑",负责:
- 解析 DAG 文件
- 根据调度规则创建 DagRun
- 决定哪些 Task 可以执行
- 将 Task 提交给 Executor
2.5 Executor(执行器)
Executor 负责实际执行 Task 的运行环境。不同的 Executor 适用于不同的部署场景:
LocalExecutor:在本地进程中执行CeleryExecutor:通过 Celery 分布式执行KubernetesExecutor:每个 Task 启动一个 K8s Pod
2.6 概念之间的关系
DAG (工作流定义) └── Task (任务节点) └── Operator (执行逻辑) Scheduler (调度决策) → Executor (执行引擎) → Worker (实际运行) ↓ TaskInstance (任务运行实例) ↓ DagRun (DAG 运行实例)3. Airflow 的架构演进:从单体到分包
3.1 Airflow 2.x 时代:单体架构
在 Airflow 2.x 中,整个项目是一个巨大的单体包apache-airflow,所有代码都在一个airflow/目录下。这种架构的问题逐渐暴露:
- 安装体积庞大:即使只编写 DAG,也需要安装完整的调度器代码
- 依赖冲突频繁:核心框架依赖与用户 DAG 依赖容易冲突
- 耦合度高:Provider 更新需要等待核心框架发版
3.2 Airflow 3.x 时代:分包架构
Airflow 3.x 进行了重大架构重组,将单体包拆分为多个独立的子项目:
airflow-main/ # 项目根目录 ├── airflow-core/ # 核心调度引擎(服务端) │ └── src/airflow/ # 包名: apache-airflow-core ├── task-sdk/ # 任务定义 SDK(客户端) │ └── src/airflow/sdk/ # 包名: apache-airflow-task-sdk ├── providers/ # 70+ 外部系统集成插件 │ ├── amazon/ # 包名: apache-airflow-providers-amazon │ ├── google/ # 包名: apache-airflow-providers-google │ ├── standard/ # 包名: apache-airflow-providers-standard │ └── ... ├── airflow-ctl/ # 命令行管理工具 │ └── src/airflowctl/ # 包名: apache-airflow-ctl ├── shared/ # 共享基础模块 │ ├── configuration/ │ ├── serialization/ │ ├── observability/ │ └── ... └── docs/ # 文档这种分包设计的核心思想是关注点分离:
| 子项目 | 职责 | 使用 |
|---|
