流批一体概述:为什么我们需要统一调度
大家好,我是这次课程的主讲。做了十几年大数据架构,我见过太多团队在流处理和批处理之间来回折腾。今天咱们先聊聊最基础的问题——流批一体到底是什么,以及为什么调度系统必须站出来扛这个活。
Lambda 架构与 Kappa 架构:两种思路的碰撞
先说说 Lambda 架构。这玩意儿在 2011 年左右特别火,我记得当时很多互联网公司都在用。它的核心思路很简单:
- 批处理层:处理全量历史数据,保证准确性
- 流处理层:处理实时增量数据,保证低延迟
- 服务层:合并两边的结果,对外提供服务
听起来挺完美对吧?但我在项目中踩过坑。Lambda 架构最大的问题就是维护两套代码。批处理用 Hive/Spark SQL,流处理用 Flink/Storm,逻辑明明一样,却要写两遍。更头疼的是,两套结果对不上时,排查起来简直要命。
后来 Kappa 架构出现了。它的想法很激进——只用一套流处理引擎,所有数据都当流来处理。历史数据重放一遍就行,不需要单独的批处理层。
| 对比维度 | Lambda 架构 | Kappa 架构 |
|---|---|---|
| 代码维护 | 两套代码,逻辑重复 | 一套代码,统一维护 |
| 资源消耗 | 批流各自独立集群 | 统一集群,资源复用 |
| 数据一致性 | 需要额外校验机制 | 天然一致,同一条处理链路 |
| 历史重跑 | 批处理直接重算 | 需要从消息队列重放 |
| 适用场景 | 对准确性要求极高 | 实时性优先,可容忍短暂延迟 |
你可能会问,那 Kappa 架构是不是完美了?也不是。我见过一些团队硬上 Kappa,结果历史数据重放时把消息队列压垮了。说白了,没有银弹,只有适合不适合。
流批一体的核心思想
流批一体,本质上是在 Lambda 和 Kappa 之间找一个平衡点。它的核心思想就三句话:
- 同一份代码:批处理和流处理共用一套逻辑,不再维护两套
- 同一套数据:源数据只存一份,不搞批流两份拷贝
- 同一个调度:批任务和流任务由统一的调度系统管理
我个人习惯把流批一体理解成「数据处理的左右手」。左手是批,负责全量、准确、可回溯;右手是流,负责增量、实时、低延迟。调度系统就是大脑,协调两只手什么时候干活、怎么配合。
举个例子。你在做用户画像,每天凌晨需要跑全量批任务更新标签,白天又要实时处理用户点击流。传统做法是批任务归 A 调度系统管,流任务归 B 调度系统管,两个系统互不通信。结果就是批任务跑完了,流任务还在处理旧数据,标签对不上。
流批一体之后,调度系统知道批任务几点结束,流任务在批任务完成后自动切换数据版本。整个过程不需要人工介入。
为什么需要统一调度
好,前面铺垫了这么多,现在聊聊最核心的问题——为什么调度系统必须站出来?
我直接说结论:没有统一调度,流批一体就是一句空话。
你想想看,流任务 7×24 小时跑着,批任务每天定点触发。如果没有统一调度,你怎么保证:
- 批任务启动时,流任务要暂停消费还是继续?
- 批任务失败重跑,流任务的实时数据要不要回退?
- 两个任务同时写同一张表,怎么避免脏数据?
这些问题的答案,都落在调度系统身上。
具体来说,统一调度要解决三个核心问题:
- 任务编排:批任务和流任务之间的依赖关系怎么定义?比如流任务必须等批任务初始化完成才能启动
- 资源协调:批流任务共享集群资源,高峰期怎么分配?低峰期怎么回收?
- 状态管理:批任务重跑时,流任务的 checkpoint 要不要回退?数据一致性怎么保证?
嗯,这里要注意。很多团队一开始觉得统一调度就是装个 Azkaban 或者 Airflow,把流任务也塞进去。结果发现流任务的「永远运行」特性和批任务的「触发运行」特性完全不一样,调度系统根本管不住。
所以后面几章,我会详细讲怎么设计一个能同时驾驭批和流的调度系统。包括任务模型怎么抽象、资源怎么分配、容错怎么处理。这些都是我在实际项目中一点点趟出来的经验。
这张图展示了我刚才讲的核心逻辑。数据源进来后,统一调度系统决定是走批处理链路还是流处理链路,或者两者并行。最终结果在合并层统一输出。注意看虚线部分——调度系统不是只管触发任务,它还会根据任务运行状态动态调整策略。
好了,第一章就聊这么多。流批一体的概念其实不难理解,难的是落地。后面我们会一步步拆解,从任务模型设计开始,到调度策略、资源管理、容错机制,每个环节我都会结合真实案例来讲。