Apache Airflow 与 Quartz 调度框架对比及选型指南
Apache Airflow 是基于 Python 的数据工作流编排平台,擅长复杂 ETL 和机器学习流程,支持 DAG 可视化与资产驱动调度。Quartz 是老牌 Java 调度库,轻量级且易嵌入,适合简单定时任务或作为底层依赖。两者各有优劣:Airflow 功能全但部署重,Quartz 轻量但需自研管理界面。选型应依据团队技术栈(Python 选 Airflow,Java 选 Quartz)、任务复杂度及运维成本决定。

Apache Airflow 是基于 Python 的数据工作流编排平台,擅长复杂 ETL 和机器学习流程,支持 DAG 可视化与资产驱动调度。Quartz 是老牌 Java 调度库,轻量级且易嵌入,适合简单定时任务或作为底层依赖。两者各有优劣:Airflow 功能全但部署重,Quartz 轻量但需自研管理界面。选型应依据团队技术栈(Python 选 Airflow,Java 选 Quartz)、任务复杂度及运维成本决定。

在分布式任务调度领域,除了我们熟知的 XXL-JOB、PowerJob 等主流框架,还有两类'小众但精锐'的方案:一类是 Python 生态的 Apache Airflow,以数据工程和机器学习工作流见长;另一类是老牌 Java 调度库 Quartz,作为众多框架的底层基石,低调而强大。
本文将带你全面认识这两个方案,并通过实战案例和深度对比,帮你找到最适合自己团队的选择。
Apache Airflow 是一个以编程方式编写、调度和监控工作流的平台。它由 Airbnb 于 2014 年开源,后成为 Apache 顶级项目。Airflow 的核心思想是'工作流即代码',所有工作流都用 Python 定义,支持动态生成、依赖编排、任务重试、监控告警等功能。
Airflow 将工作流建模为 DAG,每个节点是一个任务,边表示依赖关系。DAG 由 Python 代码定义,清晰直观。
from datetime import datetime
from airflow import DAG
from airflow.operators.bash import BashOperator
from airflow.operators.python import PythonOperator
def _extract():
print("Extract data...")
def _transform():
print("Transform data...")
def _load():
print("Load data...")
with DAG(
dag_id='etl_pipeline',
start_date=datetime(2023, 1, 1),
schedule_interval='@daily',
catchup=False
) as dag:
extract = PythonOperator(task_id='extract', python_callable=_extract)
transform = PythonOperator(task_id='transform', python_callable=_transform)
load = PythonOperator(task_id='load', python_callable=_load)
extract >> transform >> load # 定义依赖
Airflow 内置大量 Operator,覆盖各种数据生态:
从 Airflow 2.4 开始引入数据资产(Dataset)概念,工作流不再仅依赖时间,而是依赖上游产出的数据资产。当上游更新数据时,下游自动触发,实现实时化、事件驱动的调度。
from airflow.datasets import Dataset
input_dataset = Dataset('s3://my-batch/input/data.csv')
output_dataset = Dataset('s3://my-batch/output/result.csv')
with DAG(
dag_id='data_pipeline',
schedule=[input_dataset], # 依赖数据资产
... # 任务定义...
) as dag:
pass
Airflow 2.0 后 UI 使用 React 重构,界面现代化,支持网格视图、任务详情、日志预览、Gantt 图等,运维体验大幅提升。
| 组件 | 技术栈 |
|---|---|
| Web UI | React |
| Web Server | Flask |
| Scheduler | - |
| Worker | - |
| Executor | Local/Celery/K8s |
| Metadata DB | PostgreSQL/MySQL |
| 优点 | 缺点 |
|---|---|
| Python 原生,数据工程师友好 | 学习曲线较陡,需掌握 Python 和 Airflow 概念 |
| 强大的 DAG 编排能力 | 部署运维复杂,需管理元数据库、消息队列(Celery) |
| 丰富的生态算子 | 调度延迟较高(秒级),不适合高频实时任务 |
| 活跃社区,更新快 | 资源消耗较大,不适合轻量级项目 |
| 支持资产驱动调度 | 任务重试策略需显式定义 |
Quartz 是 OpenSymphony 开源组织在 Java 调度领域的老牌框架,自 2001 年发布以来,已成为 Java 定时任务的事实标准。它不是一个完整的调度平台,而是一个任务调度库,可嵌入任何 Java 应用。Spring 的 @Scheduled 底层就是 Quartz 的简化版,许多分布式调度框架(如 Elastic-Job)也基于 Quartz 二次开发。
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz</artifactId>
<version>2.3.2</version>
</dependency>
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
public class HelloJob implements Job {
@Override
public void execute(JobExecutionContext context) throws JobExecutionException {
System.out.println("Hello, Quartz! " + System.currentTimeMillis());
}
}
import org.quartz.*;
import org.quartz.impl.StdSchedulerFactory;
public class QuartzDemo {
public static void main(String[] args) throws SchedulerException {
// 1. 创建调度器
Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();
scheduler.start();
// 2. 定义 JobDetail
JobDetail job = JobBuilder.newJob(HelloJob.class)
.withIdentity("helloJob", "group1")
.build();
// 3. 定义 Trigger(每 5 秒执行一次)
Trigger trigger = TriggerBuilder.newTrigger()
.withIdentity("helloTrigger", "group1")
.startNow()
.withSchedule(SimpleScheduleBuilder.simpleSchedule()
.withIntervalInSeconds(5).repeatForever())
.build();
// 4. 调度任务
scheduler.scheduleJob(job, trigger);
}
}
Quartz 支持集群模式,通过共享数据库实现分布式协调。其原理是:多个调度器节点同时运行时,通过数据库行锁竞争执行任务。
关键表:
配置步骤:
tables_mysql.sql)。quartz.properties:org.quartz.jobStore.class=org.quartz.impl.jdbcjobstore.JobStoreTX
org.quartz.jobStore.driverDelegateClass=org.quartz.impl.jdbcjobstore.StdJDBCDelegate
org.quartz.jobStore.dataSource=myDS
org.quartz.dataSource.myDS.driver=com.mysql.cj.jdbc.Driver
org.quartz.dataSource.myDS.URL=jdbc:mysql://localhost:3306/quartz
org.quartz.dataSource.myDS.user=root
org.quartz.dataSource.myDS.password=123456
org.quartz.jobStore.isClustered=true # 开启集群
org.quartz.jobStore.clusterCheckinInterval=20000
每个节点启动相同的应用,Quartz 会自动协调,保证每个任务在同一时间只被一个节点执行。如果节点宕机,其他节点会接管。
在生产中,我们通常会对 Quartz 进行二次封装,添加任务管理、失败重试、告警等功能。下面是一个简单的封装示例(Spring Boot + Quartz):
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-quartz</artifactId>
</dependency>
@Component
public class DynamicJob extends QuartzJobBean {
@Autowired
private TaskService taskService;
@Override
protected void executeInternal(JobExecutionContext context) {
JobDataMap dataMap = context.getMergedJobDataMap();
Long taskId = dataMap.getLong("taskId");
try {
taskService.execute(taskId); // 执行成功,更新任务状态
} catch (Exception e) {
// 记录失败,根据重试策略决定是否重新调度
handleFailure(taskId, context);
}
}
}
@Service
public class QuartzService {
@Autowired
private Scheduler scheduler;
public void addTask(String name, String group, String cron, Long taskId) throws SchedulerException {
JobDetail job = JobBuilder.newJob(DynamicJob.class)
.withIdentity(name, group)
.usingJobData("taskId", taskId)
.storeDurably()
.build();
CronTrigger trigger = TriggerBuilder.newTrigger()
.withIdentity(name + "Trigger", group)
.withSchedule(CronScheduleBuilder.cronSchedule(cron))
.build();
scheduler.scheduleJob(job, trigger);
}
public void deleteTask(String name, String group) throws SchedulerException {
scheduler.deleteJob(JobKey.jobKey(name, group));
}
}
只需在 application.yml 中配置数据源,并开启 spring.quartz.job-store-type=jdbc 和 spring.quartz.properties.org.quartz.jobStore.isClustered=true。
| 维度 | Apache Airflow | Quartz |
|---|---|---|
| 核心语言 | Python | Java |
| 定位 | 工作流平台(全栈) | 调度库(嵌入式) |
| 学习曲线 | 较陡(需理解 DAG、Operator) | 平缓(基本概念简单) |
| 部署复杂度 | 高(需元数据库、消息队列、Web 服务器) | 低(直接嵌入应用) |
| 任务定义方式 | Python 代码(动态生成) | Java 代码或配置文件 |
| 分布式能力 | 原生支持(Celery/K8s 执行器) | 基于数据库行锁实现集群 |
| 任务分片 | 无原生分片,可通过动态生成实现 | 需自行实现 |
| DAG 支持 | 原生强大 | 无,需二次开发 |
| 管理界面 | 功能完善(Web UI) | 无,需自研 |
| 失败重试 | 内置重试机制 | 需自研 |
| 监控告警 | 内置邮件、可与外部集成 | 需自研 |
| 资源消耗 | 较高(需独立服务) | 极低(嵌入应用) |
| 社区生态 | 活跃,数据领域集成多 | 稳定,但更新较慢 |
| 适用团队 | 数据工程师、Python 团队 | Java 后端团队 |
| 典型场景 | 数据 Pipeline、ML 工作流 | 简单定时任务、作为底层依赖 |
两者并不互斥。例如,可以在数据平台中使用 Airflow 编排大数据任务,同时在业务系统(Java)中使用 Quartz 处理轻量级定时任务。
Apache Airflow 和 Quartz 代表了调度领域的两个极端:一个是全功能的数据工作流平台,一个是轻量级的嵌入式调度库。它们没有优劣之分,只有适用场景的不同。
理解它们的核心价值,才能在做技术选型时游刃有余。希望本文能帮助你做出明智的决策,在合适的场景使用合适的工具。

微信公众号「极客日志」,在微信中扫描左侧二维码关注。展示文案:极客日志 zeeklog
生成新的随机RSA私钥和公钥pem证书。 在线工具,RSA密钥对生成器在线工具,online
查找任何按下的键的javascript键代码、代码、位置和修饰符。 在线工具,Keycode 信息在线工具,online
JavaScript 字符串转义/反转义;Java 风格 \uXXXX(Native2Ascii)编码与解码。 在线工具,Escape 与 Native 编解码在线工具,online
基于 Mermaid.js 实时预览流程图、时序图等图表,支持源码编辑与即时渲染。 在线工具,Mermaid 预览与可视化编辑在线工具,online
使用 Prettier 在浏览器内格式化 JavaScript 或 HTML 片段。 在线工具,JavaScript / HTML 格式化在线工具,online
Terser 压缩、变量名混淆,或 javascript-obfuscator 高强度混淆(体积会增大)。 在线工具,JavaScript 压缩与混淆在线工具,online