1、增量计算概述
大家好,我是这次课程的主讲。今天咱们聊聊增量计算——这个在实时数据处理领域绕不开的核心概念。
说实话,我最早接触增量计算是在做实时数仓的时候。那时候每天要处理几十亿条用户行为日志,全量跑一次要几个小时,业务方还嫌不够快。后来我换了个思路:既然每天变化的数据只有5%,为什么非要重算那95%呢?这就是增量计算的朴素想法。
什么是增量计算
增量计算,说白了就是「只算变化的部分」。
举个例子。你有一张订单表,昨天有100万条记录。今天新增了1万条,修改了2000条。全量计算会把102.2万条全部重算一遍;增量计算只处理那1.2万条变化的数据。
我个人习惯把增量计算拆成三个要素:
- 变化捕获——怎么知道哪些数据变了?
- 变化传递——变化的数据怎么流到计算引擎?
- 状态合并——新结果怎么跟旧结果合并?
这三个要素缺一不可。我在项目中遇到过不少团队,只做了前两步,结果状态合并没处理好,数据对不上,最后还得全量重跑——嗯,这就尴尬了。
核心要点:增量计算不是简单的「只算新增数据」,而是「识别变化 → 传递变化 → 合并状态」的完整链路。
全量计算 vs 增量计算
咱们直接看对比,这样更直观。
| 对比维度 | 全量计算 | 增量计算 |
|---|---|---|
| 计算范围 | 全部数据 | 变化的数据 |
| 延迟 | 分钟~小时级 | 秒级~毫秒级 |
| 资源消耗 | 高(CPU/内存/IO) | 低(通常只有全量的5%~20%) |
| 数据一致性 | 天然一致(全量重算) | 需要额外保证(乱序、重复、延迟) |
| 实现复杂度 | 低(直接SQL即可) | 高(需要状态管理、Exactly-Once语义) |
| 适用场景 | 离线报表、数据快照、数据恢复 | 实时监控、实时数仓、CDC同步 |
你可能会问:既然全量计算简单又一致,为什么还要用增量?
我举个例子。之前有个电商客户,订单表每天增长3000万条。全量跑一次T+1报表要40分钟,业务方说「我要看实时GMV,延迟不能超过1分钟」。40分钟 vs 1分钟,全量计算直接出局。
但增量计算也有坑。我曾经在一个项目中,因为没处理好乱序数据,导致实时大屏上的销售额跳来跳去——一会儿涨100万,一会儿又跌回去。业务方差点以为系统被黑了。所以,选增量计算之前,先问问自己:你的场景能接受多少数据不一致?
我的建议:不要非此即彼。很多成熟系统是「增量为主 + 全量兜底」的混合模式。比如每5分钟做一次增量计算,每天凌晨做一次全量校准。这样既有实时性,又有最终一致性。
增量计算的应用场景
增量计算不是银弹,但它在三个场景里几乎是标配。我按自己的经验排个序:
1. 实时数仓
这是增量计算最典型的战场。实时数仓的核心诉求就是「数据从产生到可查询,延迟越低越好」。
我记得有个金融项目,需要实时计算用户的持仓市值。全量计算要扫描几亿条持仓记录,耗时太长。我们改用增量计算:只处理当天发生交易的账户,其他账户沿用昨天的计算结果。最终延迟从30分钟降到了5秒以内。
实时数仓里常见的增量计算模式:
- 实时ETL——只处理新增/变更的数据行
- 实时聚合——维护一个中间状态,新数据到来时增量更新
- 实时关联——用窗口缓存部分数据,避免全表扫描
2. 流处理
流处理本身就是增量计算的「亲儿子」。每条数据到来时,计算引擎只处理这一条,然后更新结果。
举个例子,Flink的窗口聚合:
// 全量思维:每天跑一次SQL,统计所有订单
SELECT date, SUM(amount) FROM orders GROUP BY date;
// 增量思维:每来一条订单,更新一次SUM
DataStream<Order> orders = ...;
orders
.keyBy(order -> order.getDate())
.window(TumblingProcessingTimeWindows.of(Time.days(1)))
.reduce((o1, o2) -> new Order(o1.getDate(), o1.getAmount() + o2.getAmount()));
看到区别了吗?全量是「算完所有数据再出结果」,增量是「来一条算一条」。后者天然适合流处理。
但这里有个容易踩的坑:状态管理。流处理引擎需要维护中间状态(比如窗口里的累加值),如果状态太大或者状态后端配置不当,很容易OOM。我曾经有个线上事故,就是因为状态没做TTL,结果跑了三天后状态膨胀到几百GB,直接把TaskManager撑爆了。
避坑指南:流处理中的增量计算,一定要给状态设置合理的TTL(Time-To-Live)。Flink中可以用 StateTtlConfig 控制,别等到线上出问题才想起来。
3. CDC(Change Data Capture)
CDC是增量计算的「数据源担当」。没有CDC,增量计算就是无米之炊。
CDC的核心能力是捕获数据库的变更事件(INSERT/UPDATE/DELETE),然后推送给下游。常见的CDC工具:
- Debezium——基于MySQL binlog、PostgreSQL WAL等
- Canal——阿里开源的MySQL binlog解析工具
- Maxwell——也是MySQL binlog,但输出格式更灵活
我个人的经验是:CDC + 消息队列 + 流计算引擎,是构建实时数据管道的最佳组合。比如:
MySQL binlog → Debezium → Kafka → Flink → 实时数仓
这套链路里,Debezium负责捕获增量变化,Kafka负责缓冲和分发,Flink负责增量计算。每一层各司其职。
但CDC也有坑。我记得有一次,MySQL主库做了DDL操作(加了一列),结果Debezium的schema缓存没更新,下游Flink任务直接报错。从那以后,我养成了一个习惯:CDC链路一定要做schema兼容性测试,而且要有自动化的schema演进机制。
知识体系总览
下面这张图,把本章的核心脉络串起来了。你可以把它当作增量计算的「地图」,后续章节都会围绕这些节点展开。
这张图从左到右展示了增量计算的完整脉络:从「三个要素」到「全量 vs 增量对比」,再到「三大应用场景」。你可以看到,变化捕获、变化传递、状态合并是底层能力,实时数仓、流处理、CDC是上层应用。后续章节会逐一深入每个节点。
好了,第一章就到这里。增量计算不是什么高深的技术,但它确实能解决很多实际问题。记住一句话:能算增量,就别全量重算——除非你不在乎时间和资源。