首页/数据/数据工程与 ETL 速查/Airflow 动态任务映射与 TaskGroup

Airflow 动态任务映射与 TaskGroup

动态任务映射用 task.expand(...) 按运行时列表生成一批并行任务(如按分区展开);TaskGroup 做界面上的分组折叠,不改变依赖语义,两者常配合管理复杂 DAG 的图结构。

动态任务映射是什么

动态任务映射(dynamic task mapping)让任务在运行时按一个列表展开成一批并行任务,典型场景是按分区或按表展开:展开数量由上游结果决定,而不是在写 DAG 时就固定。Airflow 2.3 起以 partial(...).expand(...) 表达。TaskGroup 则是界面上的逻辑分组,把一组任务折叠成一个可读的模块,它不改变依赖语义。两者常配合使用,用来管理结构复杂的 DAG。

基本信息

版本要求Airflow 2.3 起支持 TaskFlow 的动态映射
基本写法partial 固定参数 + expand 展开可变参数列表
多参数展开expand_kwargs 传入字典列表,一次展开多组参数
TaskGroup@task_group 装饰器或 TaskGroup 上下文,仅影响界面分组
依赖声明可整体引用 group,也可对 group 内任务逐个声明
数量约束单次映射生成的任务实例数有上限,超出会直接失败

典型使用场景

  • 按日期分区展开:一次触发生成该区间每一天一个加载任务
  • 按表或按库展开:整库同步时每张表一个独立任务,失败可单独重试
  • 按上游输出展开:上游返回处理清单,下游据此并行处理
  • 批处理切分:大文件按分片并行处理,失败只需重跑单个分片
  • 界面治理:把十几个同质任务收进一个 TaskGroup,图结构更易读

expand 与 TaskGroup

expand 与 TaskGroup
from airflow.decorators import task, task_group

@task
def load(part: str, bizdate: str) -> None:
    # 每个分区一个任务实例,可单独重试
    print(part, bizdate)

@task_group(group_id="loads")
def make_group(parts):
    # partial 固定不变参数,expand 展开可变参数
    load.partial(bizdate="2026-10-11").expand(part=parts)

make_group(["dt=2026-10-09", "dt=2026-10-10"])

展开数量与依赖检查

展开数量与依赖检查
# 查看本次运行实际生成了多少个映射任务实例
airflow tasks list daily_orders --tree
# 关注映射任务数是否与预期分区数一致,少了说明上游列表为空
airflow tasks states-for-dag-run daily_orders <run_id> | grep load

映射与分组对照

能力作用不做什么
expand运行时按列表生成多个任务实例不负责执行顺序,依赖仍要显式声明
partial固定那些每次都不变的参数不改变任务数量
TaskGroup界面分组、折叠显示不产生执行顺序,也不限制并行度
pool 与并发限制控制同一时刻能跑多少实例不改变映射生成的任务总数
映射数量在运行前就能从入参推导出来,因此不要把展开列表接在会无限增长的来源上;数量上限被触发时整条 DAG 会失败,而不是自动截断。
被跳过的分支上游若未使用合适的触发规则,下游映射任务会一起被跳过;排查「任务没跑」时先看上游分支状态,而不是先怀疑映射本身。

易错点

  • expand 的参数是空列表时映射任务不会生成,下游依赖它时状态异常且不易察觉
  • 把 TaskGroup 当成顺序控制,实际执行顺序仍由依赖关系决定,界面分组只是显示
  • 展开列表来自会持续增长的查询结果,任务实例数超出上限后整条 DAG 直接失败
  • 映射任务共享同一个资源池却不设限制,瞬间并发把下游数据库连接打满
  • 映射任务的参数拼在日志里输出敏感信息,日志留存量级被放大

数据来源与参考

  • Apache Airflow 官方文档:Dynamic Task Mapping 与 TaskGroups
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌