实时写入架构设计: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 架构」。

整体数据流设计

下面这张图是我在实际项目中用的数据流架构。你看一眼就明白了。

Delta Lake + Kafka 实时写入数据流 数据源 App / 日志 / DB Kafka 消息队列 实时处理 Structured Streaming Delta Lake 存储层 批处理 Spark Batch 下游消费 实时 / 离线 Delta Lake 时间旅行 支持任意版本回溯

整个数据流分四层:

  1. 数据接入层:各种数据源写入 Kafka。我建议用 Avro 或 Protobuf 序列化,方便 schema 演进
  2. 实时处理层:Structured Streaming 从 Kafka 消费数据,做清洗、转换、聚合。这里要注意 checkpoint 的设置,我吃过一次亏,没设 checkpoint 导致重启后数据重复
  3. 存储层:处理后的数据写入 Delta Lake。Delta Lake 的 ACID 事务保证了数据一致性,时间旅行特性方便回溯
  4. 输出层:下游应用从 Delta Lake 读取数据,可以是实时流,也可以是批处理

关键点:Delta Lake 在这里既是存储层,也是批处理层。它用时间旅行替代了 Lambda 架构中的批处理路径,同时保留了 Kappa 架构的简洁性。

我曾经在一个金融风控项目里用这个架构。数据从交易系统进入 Kafka,Structured Streaming 实时计算风险指标,结果写入 Delta Lake。风控模型需要历史数据训练时,直接从 Delta Lake 的时间旅行读取三个月前的数据。整个过程一套代码,运维轻松很多。

避坑指南:Delta Lake 的 compaction 要定期做。我遇到过小文件太多导致查询变慢的情况。建议每小时做一次 compaction,合并小文件。

总结一下这个架构的核心优势:

  • 一套代码:实时和批处理共用同一套处理逻辑
  • ACID 事务:数据一致性有保障,不会出现 Lambda 架构中的对不齐问题
  • 时间旅行:历史数据回溯不需要依赖 Kafka 的存储,Delta Lake 原生支持
  • 运维简单:一个存储层搞定实时和批处理,不需要维护两套集群