首页/数据/数据工程与 ETL 速查/并发控制:队列、池与并行度

并发控制:队列、池与并行度

调度并发要分层控制:集群总并行度、单 DAG 并发、任务池(pool)槽位、worker 执行槽。给写库与重资源任务设置独立池,避免批量任务同时压垮下游。

并发控制要分层做

调度并发需要分层控制:集群层面的总并行度、单个 DAG 的并发上限、任务池(pool)的槽位数,以及 worker 上的执行槽。这几层缺一不可:只限 DAG 而不限资源池,多个 DAG 仍会把下游数据库同时压垮;只管资源池而不看 DAG 并发,一个 DAG 自己就能占满全部槽位。

基本信息

DAG 级max_active_runs 控制同时运行的 DagRun 数,max_active_tasks 控制任务并行
任务池pool 加 slots,限制同类任务同时运行的数量
执行侧executor 的并发槽位决定同时执行的上限
实践要点写库、调接口这类有限资源单独建池,保护下游

典型使用场景

  • 数仓写入任务:单独建池,避免批量作业同时打满数据库连接
  • 外部接口调用:限制并发,防止触发对方限流与封禁
  • 大内存任务:限制同机并发数,防止内存告急
  • 多团队共享调度器:按团队配额分池,避免互相抢占
  • 大促补数:临时调整池大小,但要同步评估下游容量

池与并发配置

池与并发配置
# 建池并设置槽位:dw_etl 池最多 4 个并发槽
airflow pools set dw_etl 4 "数仓写入任务池"
airflow pools list

# 在任务里指定池与占用槽位数
# PythonOperator(task_id='load_dwd', python_callable=load_dwd,
#                pool='dw_etl', pool_slots=1, dag=dag)

# DAG 级并发:限制同时运行的任务数与 DagRun 数
# DAG('daily_orders', max_active_tasks=8, max_active_runs=1)

并发层次与失控后果

层次控制参数不控制的后果
DAG 任务并行max_active_tasks单个 DAG 抢占全部执行槽位
DAG 批次并行max_active_runs补数时多个 DagRun 同时跑,重复写数
资源池pool 与 slots下游数据库连接被打满
执行器executor 并发槽位worker 资源耗尽,任务排队或内存告急
池的价值在于保护下游:数据库写入、外部接口调用这类有限资源都应该建独立池并限制并发,用「排队但稳定」换掉「同时冲上去然后全部失败」。
池槽位不足时任务会停留在排队状态,界面上看起来像「任务卡住」,实际是在等资源;排查前先看池的占用情况,不要直接重启调度器。

易错点

  • 池槽位不足导致任务排队,被误判为任务卡死,白白浪费排查时间
  • 调大池容量时不同步评估下游容量,只是把瓶颈从调度器转移到数据库
  • 补数时未限制 max_active_runs,多个 DagRun 同时写同一分区,数据被反复覆盖
  • 所有任务共用一个默认池,重任务与轻任务互相挤占,关键链路被拖慢

数据来源与参考

  • Apache Airflow 官方文档:Pools 与 Concurrency 控制
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌