实时写入架构设计:Lambda vs Kappa,为什么选 Delta Lake + Kafka
架构选型这件事,说白了没有银弹。我在好几个实时项目里都踩过坑,今天把 Lambda 和 Kappa 的对比、以及为什么我最终选择 Delta Lake + Kafka 这个组合,一次性讲清楚。
Lambda 架构:经典但沉重
Lambda 架构大家应该不陌生。它把数据流拆成两条路:一条实时流处理,一条批处理。最后在服务层合并结果。
核心思路:用批处理保证数据准确性,用流处理保证低延迟。
我在 2018 年做过一个用户行为分析平台,当时就是 Lambda 架构。批处理跑 Hive,流处理用 Storm。结果呢?维护两套代码,逻辑经常对不上。批处理修了一个 bug,流处理那边忘了同步,数据就对不齐了。
Lambda 架构的问题很明显:
- 代码双倍:批处理和流处理各写一套逻辑,维护成本翻倍
- 数据一致性难保证:两条路径处理结果可能不同,需要额外合并逻辑
- 运维复杂:两套集群、两套监控、两套告警
注意:Lambda 架构不是不能用,但适合团队规模大、有专门批处理和流处理团队的场景。小团队建议慎重。
Kappa 架构:简洁但需要强存储
Kappa 架构就简单多了——所有数据都走实时流,没有批处理那条路。需要重算的时候,直接从 Kafka 回溯消费。
我刚开始接触 Kappa 时觉得这方案太理想了。后来在几个项目里试了试,发现它有个前提:你的消息队列必须能保存足够长时间的数据,而且重放性能要够好。
Kappa 架构的优势:
- 一套代码:流处理逻辑统一,没有批流分裂
- 运维简单:一个集群搞定
- 数据一致性天然好:没有两条路径的合并问题
但 Kappa 也有短板:
- 依赖消息队列的存储能力:Kafka 默认保存 7 天,要回溯几个月甚至几年的数据,存储成本很高
- 重算效率低:从头消费几 TB 数据,速度远不如批处理
- 历史数据修正困难:如果发现数据质量问题,需要重新消费全部数据
为什么我选 Delta Lake + Kafka
嗯,这里要说说我的真实感受。Lambda 太重,Kappa 又太依赖消息队列。我一直在想,有没有一种方案能结合两者的优点?
后来在 Databricks 的一个项目里,我尝试了 Delta Lake + Kafka 的组合。效果出乎意料的好。
| 维度 | Lambda 架构 | Kappa 架构 | Delta Lake + Kafka |
|---|---|---|---|
| 代码维护 | 两套代码 | 一套代码 | 一套代码 + Delta Lake 做批处理 |
| 数据一致性 | 需要合并逻辑 | 天然一致 | ACID 事务保证 |
| 历史回溯 | 批处理支持 | 依赖 Kafka 存储 | Delta Lake 时间旅行 |
| 运维复杂度 | 高 | 中 | 低 |
| 实时性 | 秒级 | 秒级 | 秒级 |
你想想看,Delta Lake 解决了 Kappa 架构最大的痛点——历史数据存储和重算。它用时间旅行特性,可以随时回溯到任意版本的数据。而且 Delta Lake 的 ACID 事务保证了数据一致性,不需要像 Lambda 那样做合并。
我的经验:Delta Lake + Kafka 的组合,本质上是用 Delta Lake 替代了 Lambda 架构中的批处理层,同时保留了 Kappa 架构的简洁性。你可以把它理解为「带批处理能力的 Kappa 架构」。
整体数据流设计
下面这张图是我在实际项目中用的数据流架构。你看一眼就明白了。
整个数据流分四层:
- 数据接入层:各种数据源写入 Kafka。我建议用 Avro 或 Protobuf 序列化,方便 schema 演进
- 实时处理层:Structured Streaming 从 Kafka 消费数据,做清洗、转换、聚合。这里要注意 checkpoint 的设置,我吃过一次亏,没设 checkpoint 导致重启后数据重复
- 存储层:处理后的数据写入 Delta Lake。Delta Lake 的 ACID 事务保证了数据一致性,时间旅行特性方便回溯
- 输出层:下游应用从 Delta Lake 读取数据,可以是实时流,也可以是批处理
关键点:Delta Lake 在这里既是存储层,也是批处理层。它用时间旅行替代了 Lambda 架构中的批处理路径,同时保留了 Kappa 架构的简洁性。
我曾经在一个金融风控项目里用这个架构。数据从交易系统进入 Kafka,Structured Streaming 实时计算风险指标,结果写入 Delta Lake。风控模型需要历史数据训练时,直接从 Delta Lake 的时间旅行读取三个月前的数据。整个过程一套代码,运维轻松很多。
避坑指南:Delta Lake 的 compaction 要定期做。我遇到过小文件太多导致查询变慢的情况。建议每小时做一次 compaction,合并小文件。
总结一下这个架构的核心优势:
- 一套代码:实时和批处理共用同一套处理逻辑
- ACID 事务:数据一致性有保障,不会出现 Lambda 架构中的对不齐问题
- 时间旅行:历史数据回溯不需要依赖 Kafka 的存储,Delta Lake 原生支持
- 运维简单:一个存储层搞定实时和批处理,不需要维护两套集群