Lambda 架构是一个在大数据领域非常经典的设计模式,旨在处理超大规模数据的系统,它通过结合两种不同的处理路径来平衡 延迟、容错性和可扩展性。
一、Lambda 核心思想:一个问题的两种解法
Lambda 架构的核心思想源于一个简单的观察:批量处理可靠,但速度慢;流式处理速度快,但可能不精确。那么,何不两者都用呢?
它通过创建两条独立的数据处理路径来应对大规模数据计算的挑战:
- 批处理层(Batch Layer):处理所有历史数据,提供准确、可靠的“真相”。
- 速度层(Speed Layer):处理最新的实时数据,弥补批处理层的高延迟,提供实时的视图。
最终通过服务层(Serving Layer) 将两者结果合并,提供给用户一个既完整又最新的查询结果。
下图直观地展示了 Lambda 架构的三层数据流:

1. 批处理层(Batch Layer)
管理和预处理所有的、历史的原始数据,生成一个不可变的、仅追加的主数据集,并基于这个数据集进行预计算,生成批处理视图。
-
特点:
- 高延迟:处理周期可能是小时或天级别(例如,每4小时运行一次)。
- 高容错性:计算逻辑简单(如 MapReduce),易于重算,非常健壮。
- 高准确性:由于处理了所有数据,结果是精确的。
-
技术选型:
- 存储:HDFS, S3(存放原始数据和批处理视图)
- 计算:Apache Hadoop MapReduce, Apache Spark
2. 速度层(Speed Layer)/ 流处理层
处理批处理层上次计算后产生的最新数据。只关注自上次批处理完成后到当前时刻的数据增量,并生成一个实时的、可能不精确的增量视图。
-
特点:
- 低延迟:处理是实时的,延迟在秒或毫秒级别。
- 结果近似:为了追求速度,可能会使用近似算法(如 HyperLogLog)或在发生故障时丢失少量数据。
- 复杂性高:需要处理乱序数据、状态管理等复杂问题。
-
技术选型:
- 处理框架:Apache Storm, Apache Samza, Apache Flink
- 存储:Redis, HBase(存放实时视图)
3. 服务层(Serving Layer)
响应用户的查询请求。通过合并批处理视图和实时视图,返回一个完整且最新的结果。
-
工作流程:
- 接收到查询请求。
- 从批处理层读取批处理视图(完整、精确但陈旧的结果)。
- 从速度层读取实时视图(最新但可能不精确的增量结果)。
- 将两者合并:
最终结果 = 批处理结果 + 实时增量结果。 - 将合并后的结果返回给用户。
-
技术选型:
- Apache HBase, Elasticsearch, Druid, Cassandra
二、简单的例子:网站页面浏览量统计
假设我们要统计一个网站每个页面的总浏览量(PV)。
- 数据源:用户访问产生的点击流日志。
-
批处理层:
- 每天晚上,用一个 Spark Job 处理过去24小时内所有的日志数据。
- 计算出每个页面的总PV,生成一个
[页面ID, 总PV]的批处理视图,存入HBase。 - 此时,这个视图的数据截止到昨天午夜。
-
速度层:
- 在今天白天,新的点击流日志实时流入 Kafka。
- Flink 任务实时消费这些数据,为每个页面ID累加今天的PV,并将结果(
[页面ID, 今日实时PV])存入Redis。
-
服务层:
- 当用户在下午3点查询
页面A的PV时:- 从HBase中查询
页面A截止到昨天午夜的PV(假设是10,000)。 - 从Redis中查询
页面A从今天零点到下午3点的实时PV(假设是500)。 - 将两者相加:
10,000 + 500 = 10,500。 - 返回结果10,500给用户。
- 从HBase中查询
- 当用户在下午3点查询
三、Lambda 优缺点分析
优点
- 健壮性与容错性:批处理层是系统的基础,即使速度层出错或数据丢失,只要重新处理实时数据,最终结果也能保持一致。
- 可扩展性:批处理和流处理都可以水平扩展以应对海量数据。
- 低延迟查询:通过合并两层的结果,实现了对海量数据的近实时查询。
缺点
- 系统复杂性:需要开发和维护两套独立的代码逻辑(批处理和流处理),这两套逻辑要实现相同的业务计算,但用的是不同的API和框架。这对开发和运维都是巨大的挑战。
- 维护成本高:需要管理两套独立的分布式系统集群。
- 数据口径一致性问题:确保批处理逻辑和流处理逻辑完全一致非常困难,可能导致合并后的结果出现偏差。
四、Kappa 架构——Lambda 的演进与替代
Kappa 架构的核心思想非常直接,为了简化系统的复杂性,能否只使用一套流处理逻辑来处理所有数据,无论是实时还是历史。
在 Lambda 架构中,最大的问题是需要维护两套代码(批处理和流处理)来执行相同的业务逻辑。这不仅开发成本高,而且极易出现数据口径不一致的问题。
Kappa 架构的提出者认为,很多批处理任务本质上可以被看作是“有界数据流”,而流处理则是“无界数据流”。既然流处理系统的能力越来越强,为什么不用一套流处理系统来统一处理所有场景呢?
五、Kappa 架构核心思想:一切皆流
Kappa 架构的核心原则是:
只保留 Lambda 架构中的“速度层”,并让这一层承担所有的数据处理工作。它取消了专门的“批处理层”,所有数据(包括历史数据和实时数据)都被当作流来处理。
关键组件与工作流程:
-
消息队列(持久化日志):
- 消息队列 Kappa 架构的基石。所有进入系统的原始数据都必须被发送到一个可以持久化存储的、支持数据重放的消息队列中,例如 Apache Kafka。
- Kafka 会将所有消息持久化到磁盘,并保留足够长的时间。这相当于存储了“主数据集”。
- 作用:取代了 Lambda 架构中批处理层所维护的原始数据存储(如HDFS)。
-
流处理引擎:
- 流处理引是唯一的计算层。它从消息队列中消费数据,进行处理和计算,然后将结果输出到下游的数据库或服务层。
- Apache Flink 是理想选择,因为它提供了精确一次(Exactly-Once)的语义和强大的状态管理。当然,也可以使用 Spark Streaming 等。
-
服务层/数据库:
- 与 Lambda 架构中的服务层类似,用于存储计算结果并支持查询。

六、Kappa 如何重新计算全量数据
这是理解 Kappa 架构最重要的一点。如果没有了批处理,当业务逻辑改变,或者需要重新计算历史数据时,该怎么办?
答案就是:数据重播。
步骤如下:
- 启动一个新版本的流处理作业(称之为“重算作业”)。
- 配置这个新作业,从消息队列(如Kafka)的最开始(或者从某个特定的偏移量/时间点)重新消费全部的历史数据。
- 这个新作业会使用新的业务逻辑来处理这些历史数据,并将新的计算结果输出到一个新的、临时的数据表或Topic中。
- 当这个重算作业追上实时数据的进度时,将应用程序的查询请求从旧的结果表切换到新的结果表。
- 停止旧的流处理作业,并删除旧的结果表。
七、总结
| 特性维度 | Lambda 架构 | Kappa 架构 |
|---|---|---|
| 核心理念 | 批流并存,结果合并 | 一切皆流,数据重播 |
| 架构复杂度 | 高(双路径:批处理层和速度层) | 低(单一路径:流处理层) |
| 维护成本 | 高(需要维护两套系统,批处理和流处理) | 低(只需维护一套流处理系统) |
| 数据一致性 | 可能不一致(批处理和流处理两套逻辑,需要合并) | 高(只有一套处理逻辑) |
| 实时性 | 批处理层有高延迟,速度层低延迟 | 低延迟(全流式处理) |
| 容错性 | 高(批处理层是可靠的备份) | 高(通过数据重播恢复) |
| 历史数据重算 | 自然支持(批处理层的本职工作) | 支持,但代价可能高(需重播整个数据流) |
| 技术栈 | 批处理引擎(Hadoop/Spark)+ 流处理引擎(Storm/Flink) | 统一的流处理引擎(Flink为主) + 消息队列(Kafka) |