2. Airflow核心概念
在金融ETL场景中,Airflow之所以能承担日终清算、行情补数、风控指标回算等关键任务,根本原因在于它把“调度”拆解为一组职责清晰、可独立观测的核心构件。理解这些构件之间的协作关系,比记住API更重要。本节围绕DAG、Task、Operator、Sensor、Hook、Executor、Scheduler、Metadata Database与Web UI九个概念,建立一张可落地的认知地图。
一、核心原理:声明式编排与集中式状态
Airflow采用“声明式编排 + 集中式状态”的设计。开发者用Python代码声明DAG(有向无环图),描述任务之间的依赖关系;Airflow自身不执行业务逻辑,而是把DAG解析为Task实例,交由Operator决定“做什么”,由Executor决定“在哪跑”,由Scheduler决定“何时跑”,最终把每一次运行的状态写入Metadata Database,并通过Web UI呈现。
其中,DAG是编排单元,定义调度周期、起止时间、重试策略与任务依赖;Task是DAG中的节点,是调度的最小单位;Operator是Task的模板类,如PythonOperator、BashOperator、SparkSubmitOperator;Sensor是特殊的Operator,用于等待外部条件(如文件到达、分区就绪);Hook封装外部系统连接,如HiveHook、S3Hook、HttpHook,供Operator复用;Executor负责实际执行,常见有LocalExecutor、CeleryExecutor、KubernetesExecutor;Scheduler是心脏,持续解析DAG文件、判断依赖、触发任务;Metadata Database存储DAG、Task、Run、XCom等元数据;Web UI则是观测与干预入口。
二、方法流程:一次调度到底发生了什么
以“日终行情文件到达后触发清算DAG”为例,完整链路如下:
- Scheduler周期性扫描DAG目录,解析Python文件,生成DagRun与TaskInstance,写入Metadata Database。
- Sensor(如S3KeySensor)轮询对象存储,确认行情文件已到达,返回成功。
- 依赖满足后,Scheduler将下游Task置为queued,交给Executor。
- Executor在Worker上启动进程,Operator通过Hook连接Hive/Spark执行清算逻辑。
- 任务状态、日志、XCom结果回写Metadata Database,Web UI实时刷新。
- 若失败,按DAG中
retries与retry_delay自动重试;超过上限则标记failed并触发告警。
# 金融ETL典型DAG片段
with DAG(
dag_id="fin_eod_clearing",
schedule_interval="0 2 * * *",
start_date=datetime(2024, 1, 1),
catchup=False,
default_args={
"retries": 3,
"retry_delay": timedelta(minutes=5),
"on_failure_callback": alert_dingtalk,
},
) as dag:
wait_file = S3KeySensor(
task_id="wait_market_file",
bucket_name="fin-market",
bucket_key="dt={{ ds }}/quotes.csv",
poke_interval=60,
timeout=3600,
)
clear = SparkSubmitOperator(
task_id="run_clearing",
application="s3://fin-jobs/clearing.jar",
conn_id="spark_prod",
)
wait_file >> clear
三、案例场景:构件如何各司其职
假设某券商需要在每日凌晨2点完成“行情落地→清算→风控指标→报表推送”四步链路。DAG负责声明四步依赖与重试策略;Sensor等待上游文件;PythonOperator与SparkSubmitOperator分别承担轻量校验与重计算;HiveHook、S3Hook复用连接配置;CeleryExecutor把Spark任务分发到计算集群;Scheduler按cron触发;Metadata Database记录每次Run的耗时与失败原因;Web UI供运维在早盘前快速定位卡点并手动重跑。
| 构件 | 核心职责 | 金融ETL中的典型用法 |
|---|---|---|
| DAG | 声明依赖与调度策略 | 日终清算、行情补数、指标回算 |
| Task | 调度最小单位 | 单个校验、单个分区写入 |
| Operator | 定义任务类型 | SparkSubmit、Python、Bash |
| Sensor | 等待外部条件 | 等待行情文件、分区就绪 |
| Hook | 封装外部连接 | Hive、S3、HTTP、数据库 |
| Executor | 决定执行位置 | Celery分发、K8s弹性扩缩 |
| Scheduler | 解析与触发 | cron触发、依赖判断 |
| Metadata DB | 集中存储状态 | Run历史、XCom、日志索引 |
| Web UI | 观测与干预 | 查看Gantt、清除重跑、看日志 |
四、误区与复盘
误区一:把DAG当脚本写。在DAG文件顶层执行数据库查询或大文件读取,会导致Scheduler解析变慢甚至阻塞。正确做法是把重逻辑放进Operator的可调用对象中。
误区二:Sensor滥用。大量长时间poke的Sensor会占用Worker槽位。金融场景建议使用mode="reschedule"或改用Triggerer。
误区三:忽视Metadata Database性能。高频短任务会产生海量TaskInstance记录,需定期清理并配置合适的数据库连接池。
复盘要点:排查调度问题时,先看Web UI的Task状态与日志,再查Metadata Database中的task_instance与dag_run表,最后确认Scheduler与Executor的日志。Hook连接失败优先检查Connection配置,而非修改DAG代码。