一、批处理调度概述
1.1 什么是批处理
批处理,说白了就是「攒一批活儿,一次性干完」。
我刚开始接触分布式系统时,对批处理的理解很朴素——不就是写个脚本,半夜跑一跑嘛。后来真正上手才发现,事情远没那么简单。
批处理的核心特征,我总结为三点:
- 数据有界——处理的数据集是确定的、有限的。你今天跑的是昨天的订单,数据量是已知的。
- 非实时触发——不是用户点一下就要立刻响应,而是按时间窗口(比如每天凌晨2点)或数据量阈值触发。
- 全量或增量扫描——要么把整个数据集过一遍,要么只处理上次运行以来新增的数据。
我个人的定义:批处理是一种「先收集、后处理」的计算模式。它不追求秒级响应,但追求吞吐量和数据完整性。
举个例子。你在电商平台下单后,订单状态立刻变成「已支付」,这是实时处理。但到了月底,财务系统要统计所有订单的毛利、成本、退款率——这就是批处理。它不会在你下单那一刻就算,而是等数据攒够了,统一算一笔账。
1.2 批处理与实时处理的区别
很多人问我:批处理和实时处理,到底怎么选?
我的回答是:看业务能不能等。
能等几秒甚至几分钟的,用批处理。一秒都不能等的,用实时处理。但现实往往更复杂——同一个系统里,两种模式经常混着用。
下面这张表,是我在项目中反复对比后整理的:
| 对比维度 | 批处理 | 实时处理 |
|---|---|---|
| 延迟要求 | 分钟级~天级 | 毫秒级~秒级 |
| 数据范围 | 有界数据集(全量或增量) | 无界数据流(持续到达) |
| 触发方式 | 定时调度 / 手动触发 | 事件驱动 / 持续消费 |
| 吞吐量 | 高(可批量处理百万级记录) | 中低(每条记录独立处理) |
| 容错策略 | 重试整个批次 / 断点续传 | 逐条重试 / 死信队列 |
| 典型场景 | 报表生成、数据仓库ETL、对账 | 风控拦截、实时推荐、监控告警 |
| 资源消耗 | 集中爆发(跑批时CPU/IO飙升) | 平稳持续(资源占用较均匀) |
一个小经验:我曾经接手过一个对账系统,原本用实时流处理,每条交易都去核对,结果数据库连接池被打爆了。后来改成批处理——每5分钟攒一批,批量核对,系统瞬间稳了。所以别迷信实时,批处理在特定场景下反而更可靠。
1.3 批处理调度的核心概念
做批处理调度,有几个概念你必须吃透。我按重要程度排个序:
1.3.1 作业(Job)与任务(Task)
作业是调度的最小单元。一个作业可以拆成多个任务,任务之间可能有依赖关系。
举个例子。我做一个「每日销售报表」的批处理作业:
- 作业:每日销售报表生成
- 任务1:从MySQL拉取订单数据
- 任务2:从Redis拉取实时销量缓存
- 任务3:合并数据并计算汇总
- 任务4:写入报表数据库
任务1和任务2可以并行跑,但任务3必须等它们都完成才能开始。这就是依赖关系。
1.3.2 调度策略
调度策略决定了「什么时候跑、怎么跑」。常见的策略有:
- 定时调度:每天凌晨2点、每周一早上8点……用Cron表达式控制。
- 依赖触发:上游作业跑完了,下游自动启动。比如「数据清洗」跑完才触发「数据加载」。
- 数据驱动:某个目录有新文件到达,或者数据库表行数超过阈值,就触发作业。
- 手动触发:运维人员点一下按钮,或者调用API启动。
注意:我曾经踩过一个坑——把定时调度和依赖触发混用,结果同一个作业被同时触发了两次,导致数据重复写入。后来我强制规定:一个作业只能有一种触发方式,除非你做了幂等处理。
1.3.3 数据一致性保证
这是批处理调度里最头疼的问题。我简单说几个关键点:
- 原子性:一批数据要么全部处理成功,要么全部回滚。不能出现「一半入库、一半失败」的情况。
- 幂等性:同一个作业跑两次,结果应该一样。如果下游不支持幂等,你就得自己加去重逻辑。
- 状态管理:作业跑到哪一步了?失败了从哪重试?这些状态必须持久化,不能只存在内存里。
1.3.4 容错与重试
批处理作业跑几个小时,中间网络闪断、数据库超时、磁盘满了……什么都有可能发生。
我个人的容错原则是:
- 能重试的,别直接失败。比如网络超时,重试3次再说。
- 重试要有退避策略。别一秒重试10次,把系统打垮了。用指数退避,第一次等1秒,第二次等2秒,第三次等4秒。
- 超过重试次数,进死信队列。人工介入处理,别让作业卡死在那里。
1.3.5 监控与告警
批处理作业半夜跑,你不能一直盯着屏幕。所以监控必须到位:
- 作业状态:成功、失败、运行中、等待中……一目了然。
- 执行耗时:昨天跑了30分钟,今天跑了2小时,肯定有问题。
- 数据量校验:输入100万条,输出只有80万条?赶紧告警。
我的习惯:每个批处理作业的最后一步,都加一个「数据对账」任务。比如统计输入行数、输出行数、异常行数,写入监控表。这样第二天早上看一眼就知道有没有问题,不用翻日志。
1.4 批处理调度核心架构图
下面这张图,是我根据多年经验总结的批处理调度核心架构。它涵盖了从作业提交到数据落地的完整链路:
1.5 本章小结
批处理调度,说白了就是「在正确的时间,用正确的方式,把正确的数据处理好」。
这一章我们聊了:
- 批处理是什么——攒一批活儿,一次性干完
- 和实时处理的区别——延迟、吞吐、容错策略都不一样
- 核心概念——作业与任务、调度策略、数据一致性、容错、监控
这些是基础中的基础。后面的章节,我们会深入到每个细节里去——调度引擎怎么设计、数据一致性怎么保证、分布式环境下怎么容错……
嗯,先把地基打牢,后面才好盖楼。