引言
"如果你的代码需要按顺序执行、需要定时触发、需要处理失败重试,你就需要一个调度器。"
这是「每日一个开源项目」系列的第 177 篇 。今天的项目是 Apache Airflow ------ 用 Python 编写和调度工作流的平台,数据工程领域最广泛使用的开源工具之一。
在谈技术之前,先回答一个问题:Airflow 到底能做什么?
简单说:任何需要"按顺序执行多个步骤,步骤之间有依赖关系,需要定时或按条件触发"的工作,都可以用 Airflow 管理。 最典型的是数据管道------每天凌晨从数据库拉数据、清洗、写入数据仓库、生成报表。但它不止于此:训练机器学习模型、发送邮件报告、自动化基础设施操作,都有真实的生产用例。
46,400 颗 Star,Apache 2.0,版本 3.3.0,全球数千家公司在生产环境使用。
你会学到什么
- Airflow 能解决哪四类核心问题(重点)
- DAG 是什么,为什么用图来描述工作流
- Operator 和 Provider:600+ 内置集成覆盖哪些系统
- Airflow 3.0 的关键新特性:事件驱动调度和 Asset 感知
- 快速上手:用 10 行 Python 写一个真实 DAG
- 什么时候该用 Airflow,什么时候不该用
前提知识
- 会写基础 Python
- 了解"定时任务"的概念(cron 等)
- 对数据处理流程有基本认知(不需要是专业数据工程师)
Airflow 能做什么(核心问题)
这是本文最重要的部分。
场景一:ETL/ELT 数据管道
最主要的用途。 数据工程师每天面对的典型问题:
markdown
每天凌晨 2 点:
1. 从 MySQL 业务数据库拉取昨天的订单数据
2. 清洗和转换(去重、格式标准化、补充维度数据)
3. 写入 BigQuery / Snowflake 数据仓库
4. 更新 BI 报表
5. 如果第 3 步失败,发 Slack 告警并重试
这 5 步有严格的执行顺序,步骤 4 必须在步骤 3 成功后才能运行。
Airflow 把这个流程写成一个 DAG,配置好依赖关系,每天自动触发,每步失败都有记录,重试逻辑可配置,所有历史执行都在 Web UI 里可查。
真实规模:Airbnb(Airflow 的创始公司)最初用它管理每天数百个 ETL 任务。现在有公司在生产环境跑几千个 DAG,每天执行数十万个任务。
场景二:机器学习训练流水线
MLOps 场景越来越普遍:
markdown
每周一:
1. 从数据仓库拉取最新训练数据
2. 特征工程(归一化、编码、拆分训练/测试集)
3. 训练模型(可以是 Python 脚本、也可以提交到 Spark 集群)
4. 评估模型指标(精确率、召回率、AUC)
5. 如果指标超过阈值,自动部署到生产环境
6. 如果低于阈值,通知数据科学团队
步骤 5 和 6 是条件分支------Airflow 的 BranchPythonOperator 支持基于上一步结果做不同处理。
场景三:定时报表和数据同步
不需要是复杂的大数据场景:
- 每天早上 9 点把昨天的销售数据发给管理层(邮件 + Excel 附件)
- 每小时把 CRM 里的新客户数据同步到营销平台
- 每周五把各部门的 KPI 汇总后写入 Google Sheets
- 每月 1 号生成上月财务报表并上传 S3
这些工作以前靠 cron + shell 脚本处理,Airflow 提供了可观察性:每次执行成不成功、哪步慢了、失败后怎么处理,一目了然。
场景四:基础设施自动化
Airflow 不限于数据场景:
- 每天检测 S3 里超过 30 天的文件并归档压缩
- 生产环境数据库的定时备份和备份验证
- 自动化的云资源扩缩容(高峰期扩、低谷期缩)
- CI/CD 管道中的集成测试编排
核心概念:DAG
为什么用"图"来描述工作流
DAG = Directed Acyclic Graph,有向无环图。每个节点是一个任务(Task),节点之间的边表示"必须先完成 A,才能开始 B"的依赖关系。"无环"确保不会出现死锁(A 等 B,B 等 A)。
一个典型的 DAG(数据管道):
extract_data ──→ transform_data ──→ load_to_warehouse ──→ send_report
↓
validate_schema ──→ quarantine_bad_data
Airflow 用 Python 定义这个图:
python
from airflow import DAG
from airflow.operators.python import PythonOperator
from airflow.operators.bash import BashOperator
from datetime import datetime, timedelta
# DAG 定义
with DAG(
dag_id="daily_sales_pipeline",
schedule="0 2 * * *", # 每天凌晨 2 点
start_date=datetime(2026, 1, 1),
catchup=False,
default_args={
"retries": 2,
"retry_delay": timedelta(minutes=5),
},
) as dag:
# 任务 1:从数据库提取数据
extract = PythonOperator(
task_id="extract_data",
python_callable=extract_from_mysql,
)
# 任务 2:数据转换和清洗
transform = PythonOperator(
task_id="transform_data",
python_callable=clean_and_transform,
)
# 任务 3:写入数据仓库
load = PythonOperator(
task_id="load_to_warehouse",
python_callable=load_to_bigquery,
)
# 任务 4:发送报告
report = BashOperator(
task_id="send_report",
bash_command="python send_email.py --date {{ ds }}",
)
# 定义依赖关系(执行顺序)
extract >> transform >> load >> report
这 40 行 Python 就是一个完整的生产数据管道。Airflow 负责在凌晨 2 点触发它,按顺序执行每个任务,失败时重试,在 Web UI 里展示每次运行的状态。
调度方式
Airflow 支持多种触发方式:
python
# 定时调度(标准 cron 表达式)
schedule="0 9 * * 1-5" # 工作日早上 9 点
# Airflow 内置快捷方式
schedule="@daily" # 每天
schedule="@hourly" # 每小时
schedule="@weekly" # 每周
# 3.0 新增:Asset 事件触发(数据驱动调度)
from airflow.sdk import Asset
schedule=Asset("s3://my-bucket/raw-data/") # 当这个数据集更新时触发
参数化和动态 DAG
因为 DAG 是 Python 代码,可以用 Python 的全部能力动态生成:
python
# 用循环为 10 个地区各生成一个相同结构的任务
for region in ["us-east", "eu-west", "ap-south", ...]:
PythonOperator(
task_id=f"process_{region}",
python_callable=process_region,
op_kwargs={"region": region},
)
Operator 和 Provider:600+ 内置集成
Operator 是 Airflow 的"任务模板"------每种 Operator 封装了与特定系统交互的逻辑。
内置 Operator(无需额外安装)
| Operator | 用途 |
|---|---|
PythonOperator |
执行任意 Python 函数 |
BashOperator |
执行 Shell 命令 |
BranchPythonOperator |
根据条件选择执行分支 |
EmailOperator |
发送邮件 |
HttpOperator |
调用 HTTP API |
TriggerDagRunOperator |
触发另一个 DAG |
ShortCircuitOperator |
条件不满足时跳过后续任务 |
Provider 包(按需安装)
Provider 是针对特定平台的 Operator 集合,pip install apache-airflow-providers-XXX 安装:
云服务
aws--- S3、Redshift、EMR、Lambda、Glue、SageMakergoogle--- BigQuery、GCS、Dataflow、Vertex AI、Pub/Subazure--- Blob Storage、Data Lake、Synapse、Azure ML
数据库
postgres、mysql、snowflake、databricks、spark
消息队列
apache-kafka、rabbitmq、redis
其他工具
slack、github、http、ssh、docker、kubernetes
实际写一个从 S3 读数据写入 BigQuery 的任务:
python
from airflow.providers.amazon.aws.operators.s3 import S3FileTransformOperator
from airflow.providers.google.cloud.transfers.s3_to_gcs import S3ToGCSOperator
from airflow.providers.google.cloud.operators.bigquery import BigQueryInsertJobOperator
# S3 数据 → Google Cloud Storage → BigQuery
s3_to_gcs = S3ToGCSOperator(
task_id="s3_to_gcs",
bucket="my-s3-bucket",
prefix="data/2026-08-03/",
dest_gcs="gs://my-gcs-bucket/",
)
bq_load = BigQueryInsertJobOperator(
task_id="load_to_bq",
configuration={
"load": {
"sourceUris": ["gs://my-gcs-bucket/data/*"],
"destinationTable": {
"projectId": "my-project",
"datasetId": "sales",
"tableId": "daily_orders",
},
}
},
)
s3_to_gcs >> bq_load
Airflow 3.0 的关键变化
Airflow 3.0 于 2025 年发布,两个最重要的新特性:
事件驱动调度(Asset Watchers)
3.0 之前,Airflow 主要靠 cron 定时触发------每天固定时间跑,不管数据是否已经准备好。
3.0 引入了 Asset(数据资产)概念:DAG 可以"订阅"一个数据资产,当这个资产更新时自动触发,而不是等固定时间。
python
from airflow.sdk import Asset, DAG
# 定义一个数据资产
raw_orders = Asset("s3://data-lake/raw/orders/")
# 这个 DAG 在 raw_orders 数据集更新时触发
with DAG(
dag_id="process_orders",
schedule=raw_orders, # 数据驱动,不是时间驱动
):
...
还支持 Asset Watcher,持续监听消息队列(Kafka、SQS 等),实现近实时的事件驱动:
python
from airflow.providers.standard.asset.watchers import KafkaAssetWatcher
my_asset = Asset(
"orders-stream",
watchers=[KafkaAssetWatcher(topic="new-orders", ...)],
)
DAG 版本控制
3.0 给每个 DAG 增加了版本号。修改 DAG 代码后,旧的历史运行记录保留原版本快照,新的运行使用新版本。这解决了一个长期痛点:以前修改 DAG 会导致历史记录对不上。
Web UI:可视化监控
Airflow 的 Web UI 是它的核心卖点之一。启动后在浏览器里能看到:
Grid 视图:每个 DAG 每次运行的所有任务状态,按时间从左到右排列,绿色=成功,红色=失败,黄色=运行中。一眼看出哪个时间段出了问题。
Graph 视图:DAG 的有向图,节点颜色反映当前运行状态,点击节点可以看日志、重新运行单个任务、查看执行时间。
Assets 视图(3.0 新增):数据资产的依赖关系图,展示哪些 DAG 生产数据、哪些 DAG 消费数据。
快速开始
安装(最简单方式)
bash
# 创建虚拟环境
python -m venv airflow-env
source airflow-env/bin/activate
# 安装 Airflow(约束文件确保依赖版本兼容)
AIRFLOW_VERSION=3.3.0
PYTHON_VERSION=3.12
CONSTRAINT_URL="https://raw.githubusercontent.com/apache/airflow/constraints-${AIRFLOW_VERSION}/constraints-${PYTHON_VERSION}.txt"
pip install "apache-airflow==${AIRFLOW_VERSION}" --constraint "${CONSTRAINT_URL}"
# 初始化数据库并启动(开发用,单机模式)
airflow standalone
浏览器打开 http://localhost:8080,用 admin/admin 登录。
生产部署
生产环境推荐用官方 Helm chart 部署到 Kubernetes:
bash
helm repo add apache-airflow https://airflow.apache.org
helm install airflow apache-airflow/airflow \
--namespace airflow \
--create-namespace
或使用托管服务:Astronomer(商业托管)、Amazon MWAA、Google Cloud Composer。
什么时候该用,什么时候不该用
适合 Airflow 的场景
- 批处理工作流:步骤之间有明确依赖,需要定时或按事件触发
- 需要可观察性:哪次失败了、哪步慢了、要能回溯历史
- 多系统集成:数据在 MySQL → Spark → S3 → Snowflake 之间流动
- 团队协作:多个数据工程师共同维护大量管道
不适合 Airflow 的场景
- 流处理:需要毫秒级延迟的实时流处理,用 Kafka Streams 或 Flink
- 简单 cron 任务:只是定时执行一个脚本,crontab 就够了,不需要引入 Airflow
- 纯 API 服务:Airflow 是调度器,不是 Web 框架
- 极短间隔触发:每秒触发的任务不适合 Airflow,它的调度粒度是分钟级
项目地址与资源
- 🌟 GitHub : apache/airflow
- 📖 官方文档 : airflow.apache.org/docs
- 🌐 官网 : airflow.apache.org
- 📦 PyPI : pypi.org/project/apa...
- 💬 Slack 社区 : s.apache.org/airflow-sla...
总结
Airflow 解决的问题用一句话概括:把"一串有依赖关系的任务"从手工维护的脚本,变成可以定时触发、失败自动重试、执行历史可查、团队共同维护的工程化工作流。
它的核心价值不是"帮你执行任务",而是"管理任务之间的关系"------谁先谁后、谁依赖谁、失败了怎么办、成功后通知谁、数据准备好了自动触发。
Airflow 3.0 把触发方式从"定时"扩展到"数据就绪",让整个管道从时间驱动变成事件驱动。这对数据仓库场景的意义很大:不再需要在凌晨 2 点固定等待上游数据,而是上游数据一到,下游任务立刻开始。
46,000 颗 Star,17 年的积累,生产环境跑了十年的验证------如果你的工作涉及数据管道、定时任务或多步骤自动化,Airflow 是目前社区最成熟的选择。
探索 PrimeSkills ------ 精选 AI Agent 与技能的市场,每一个都经过真实企业工作流验证,去掉浮夸,留下真正有用的。
欢迎访问我的个人主页,发现更多有价值的见解和有趣的产品。