从 Lambda 架构到 Kappa 架构

Lambda 架构是一个在大数据领域非常经典的设计模式,旨在处理超大规模数据的系统,它通过结合两种不同的处理路径来平衡 延迟、容错性可扩展性


一、Lambda 核心思想:一个问题的两种解法

Lambda 架构的核心思想源于一个简单的观察:批量处理可靠,但速度慢;流式处理速度快,但可能不精确。那么,何不两者都用呢?

它通过创建两条独立的数据处理路径来应对大规模数据计算的挑战:

  1. 批处理层(Batch Layer):处理所有历史数据,提供准确、可靠的“真相”。
  2. 速度层(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)

响应用户的查询请求。通过合并批处理视图和实时视图,返回一个完整且最新的结果。

  • 工作流程
    1. 接收到查询请求。
    2. 从批处理层读取批处理视图(完整、精确但陈旧的结果)。
    3. 从速度层读取实时视图(最新但可能不精确的增量结果)。
    4. 将两者合并:最终结果 = 批处理结果 + 实时增量结果
    5. 将合并后的结果返回给用户。
  • 技术选型
    • Apache HBase, Elasticsearch, Druid, Cassandra

二、简单的例子:网站页面浏览量统计

假设我们要统计一个网站每个页面的总浏览量(PV)。

  • 数据源:用户访问产生的点击流日志。
  • 批处理层
    • 每天晚上,用一个 Spark Job 处理过去24小时内所有的日志数据。
    • 计算出每个页面的总PV,生成一个 [页面ID, 总PV] 的批处理视图,存入HBase。
    • 此时,这个视图的数据截止到昨天午夜。
  • 速度层
    • 在今天白天,新的点击流日志实时流入 Kafka。
    • Flink 任务实时消费这些数据,为每个页面ID累加今天的PV,并将结果([页面ID, 今日实时PV])存入Redis。
  • 服务层
    • 当用户在下午3点查询 页面A 的PV时:
      1. 从HBase中查询 页面A 截止到昨天午夜的PV(假设是10,000)。
      2. 从Redis中查询 页面A 从今天零点到下午3点的实时PV(假设是500)。
      3. 将两者相加:10,000 + 500 = 10,500
      4. 返回结果10,500给用户。

三、Lambda 优缺点分析

优点
  1. 健壮性与容错性:批处理层是系统的基础,即使速度层出错或数据丢失,只要重新处理实时数据,最终结果也能保持一致。
  2. 可扩展性:批处理和流处理都可以水平扩展以应对海量数据。
  3. 低延迟查询:通过合并两层的结果,实现了对海量数据的近实时查询。
缺点
  1. 系统复杂性:需要开发和维护两套独立的代码逻辑(批处理和流处理),这两套逻辑要实现相同的业务计算,但用的是不同的API和框架。这对开发和运维都是巨大的挑战。
  2. 维护成本高:需要管理两套独立的分布式系统集群。
  3. 数据口径一致性问题:确保批处理逻辑和流处理逻辑完全一致非常困难,可能导致合并后的结果出现偏差。

四、Kappa 架构——Lambda 的演进与替代

Kappa 架构的核心思想非常直接,为了简化系统的复杂性,能否只使用一套流处理逻辑来处理所有数据,无论是实时还是历史。

在 Lambda 架构中,最大的问题是需要维护两套代码(批处理和流处理)来执行相同的业务逻辑。这不仅开发成本高,而且极易出现数据口径不一致的问题。

Kappa 架构的提出者认为,很多批处理任务本质上可以被看作是“有界数据流”,而流处理则是“无界数据流”。既然流处理系统的能力越来越强,为什么不用一套流处理系统来统一处理所有场景呢?

五、Kappa 架构核心思想:一切皆流

Kappa 架构的核心原则是:

只保留 Lambda 架构中的“速度层”,并让这一层承担所有的数据处理工作。它取消了专门的“批处理层”,所有数据(包括历史数据和实时数据)都被当作流来处理。

关键组件与工作流程:
  1. 消息队列(持久化日志)

    • 消息队列 Kappa 架构的基石。所有进入系统的原始数据都必须被发送到一个可以持久化存储的、支持数据重放的消息队列中,例如 Apache Kafka。
    • Kafka 会将所有消息持久化到磁盘,并保留足够长的时间。这相当于存储了“主数据集”。
    • 作用:取代了 Lambda 架构中批处理层所维护的原始数据存储(如HDFS)。
  2. 流处理引擎

    • 流处理引是唯一的计算层。它从消息队列中消费数据,进行处理和计算,然后将结果输出到下游的数据库或服务层。
    • Apache Flink 是理想选择,因为它提供了精确一次(Exactly-Once)的语义和强大的状态管理。当然,也可以使用 Spark Streaming 等。
  3. 服务层/数据库

    • 与 Lambda 架构中的服务层类似,用于存储计算结果并支持查询。

六、Kappa 如何重新计算全量数据

这是理解 Kappa 架构最重要的一点。如果没有了批处理,当业务逻辑改变,或者需要重新计算历史数据时,该怎么办?

答案就是:数据重播。

步骤如下:

  1. 启动一个新版本的流处理作业(称之为“重算作业”)。
  2. 配置这个新作业,从消息队列(如Kafka)的最开始(或者从某个特定的偏移量/时间点)重新消费全部的历史数据
  3. 这个新作业会使用新的业务逻辑来处理这些历史数据,并将新的计算结果输出到一个新的、临时的数据表或Topic中。
  4. 当这个重算作业追上实时数据的进度时,将应用程序的查询请求从旧的结果表切换到新的结果表
  5. 停止旧的流处理作业,并删除旧的结果表。

七、总结

特性维度 Lambda 架构 Kappa 架构
核心理念 批流并存,结果合并 一切皆流,数据重播
架构复杂度 高(双路径:批处理层和速度层) 低(单一路径:流处理层)
维护成本 高(需要维护两套系统,批处理和流处理) 低(只需维护一套流处理系统)
数据一致性 可能不一致(批处理和流处理两套逻辑,需要合并) 高(只有一套处理逻辑)
实时性 批处理层有高延迟,速度层低延迟 低延迟(全流式处理)
容错性 高(批处理层是可靠的备份) 高(通过数据重播恢复)
历史数据重算 自然支持(批处理层的本职工作) 支持,但代价可能高(需重播整个数据流)
技术栈 批处理引擎(Hadoop/Spark)+ 流处理引擎(Storm/Flink) 统一的流处理引擎(Flink为主) + 消息队列(Kafka)
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容