2. 批处理与流处理基础

在构建批流一体图谱API之前,必须深刻理解批处理与流处理的核心原理、主流引擎的架构差异,以及两种架构模式的演进路径。本章将系统梳理MapReduce/Spark的批处理原理、Flink/Storm的流处理原理,并对比Lambda与Kappa两种经典架构。

2.1 批处理原理:MapReduce 与 Spark

批处理(Batch Processing)的核心特征是对有界、静态的数据集进行一次性全量计算,强调高吞吐、高延迟(秒级到小时级)。

2.1.1 MapReduce 计算模型

MapReduce 是 Google 提出的经典批处理范式,分为两个阶段:

  • Map 阶段:将输入数据切分为独立分片,每个分片由 Map 任务并行处理,输出键值对。
  • Shuffle 阶段:对 Map 输出的键值对进行分区、排序、合并,将相同键的数据路由到同一个 Reduce 任务。
  • Reduce 阶段:对每个键对应的值列表进行聚合计算,输出最终结果。
关键特征:数据落盘(HDFS)→ 计算移动(而非数据移动)→ 高容错(任务级重试)→ 磁盘I/O密集。

2.1.2 Spark 计算模型

Spark 在 MapReduce 基础上引入 RDD(弹性分布式数据集) 和 DAG(有向无环图) 执行引擎,将中间结果尽可能保留在内存中,避免频繁磁盘I/O。

对比维度 MapReduce Spark
数据存储 中间结果强制落盘(HDFS) 优先内存缓存,内存不足时溢写到磁盘
执行模型 固定两阶段(Map + Reduce) DAG 多阶段(可包含多个宽依赖)
延迟 分钟级(磁盘I/O瓶颈) 秒级(内存计算)
编程接口 仅 Java(原生) Scala / Java / Python / SQL
容错机制 任务级重试 + 数据副本 RDD Lineage 血统重算
实战提示:在批流一体图谱API中,批处理层通常使用 Spark 进行全量历史数据重建(如全量实体关系图构建),利用其内存计算优势加速大规模图遍历与聚合。
批处理架构对比:MapReduce vs Spark MapReduce 架构 HDFS 输入分片 Map 任务(并行处理) Shuffle + 排序(磁盘I/O) Reduce 任务(聚合输出) Spark 架构 HDFS / 外部数据源 RDD 创建(内存缓存) DAG 调度 + 宽窄依赖 Action 触发计算(内存优先) MapReduce 中间结果强制落盘 → 磁盘I/O瓶颈;Spark 优先内存缓存 → 性能提升 10~100 倍

2.2 流处理原理:Flink 与 Storm

流处理(Stream Processing)的核心特征是对无界、动态的数据流进行持续、低延迟计算,强调毫秒级延迟、事件时间语义、状态管理与精确一次语义。

2.2.1 Storm 流处理模型

Storm 是早期的分布式流处理框架,采用 Topology(拓扑) 描述计算逻辑:

  • Spout:数据源,从外部系统读取数据流并发射元组(Tuple)。
  • Bolt:处理节点,接收元组并执行过滤、聚合、连接等操作。
  • Stream Grouping:定义元组在 Bolt 之间的分发策略(Shuffle、Fields、All 等)。
局限性:Storm 采用 at-least-once 语义(通过 ACK 机制),无法原生保证精确一次;状态管理依赖外部存储(如 Redis),延迟较高;不支持事件时间语义。

2.2.2 Flink 流处理模型

Flink 是新一代流处理引擎,核心设计理念是 流就是数据,批是流的特例:

  • DataStream API:以数据流为中心,支持事件时间(Event Time)、处理时间(Processing Time)、摄入时间(Ingestion Time)。
  • Checkpoint 机制:基于分布式快照(Chandy-Lamport 算法变种),实现精确一次(Exactly-Once)语义。
  • 状态后端:支持 MemoryStateBackend、FsStateBackend、RocksDBStateBackend,管理算子状态。
  • Watermark:用于处理乱序事件,触发窗口计算。
对比维度 Storm Flink
处理语义 At-least-once(ACK 机制) Exactly-Once(Checkpoint + 两阶段提交)
时间语义 仅处理时间 事件时间 / 处理时间 / 摄入时间
状态管理 依赖外部存储 内置状态后端(内存 / 文件 / RocksDB)
窗口支持 有限窗口(需手动实现) 滚动 / 滑动 / 会话窗口 + 自定义窗口
延迟 毫秒级(但状态访问慢) 毫秒级(状态本地化)
容错恢复 重放数据(可能重复) 精确恢复(Checkpoint + 对齐)
实战提示:在批流一体图谱API中,流处理层通常使用 Flink 处理实时增量数据(如实时实体关系变更、属性更新),利用其事件时间语义保证图谱数据的时间一致性。
流处理架构对比:Storm vs Flink Storm 架构 Spout(数据源) Bolt 1(过滤/转换) Bolt 2(聚合/连接) 外部存储(状态管理) Flink 架构 DataStream(事件流) 算子链 + Watermark 状态后端 + Checkpoint Sink(精确一次输出) Storm 状态依赖外部存储 → 延迟高;Flink 内置状态后端 + Checkpoint → 低延迟 + 精确一次

2.3 Lambda 架构与 Kappa 架构对比

在批流一体系统设计中,架构选型直接决定数据一致性、开发复杂度和运维成本。两种主流架构模式如下:

2.3.1 Lambda 架构

Lambda 架构由 Nathan Marz 提出,将数据处理分为三层:

  • 批处理层(Batch Layer):使用 MapReduce / Spark 对全量历史数据进行计算,生成不可变的批视图(Batch View)。
  • 流处理层(Speed Layer):使用 Storm / Flink 对实时增量数据进行计算,生成近实时视图(Real-time View)。
  • 服务层(Serving Layer):合并批视图与实时视图,对外提供统一查询接口。
优点:容错性强(批处理可重算)、历史数据完整、实时延迟低。
缺点:两套代码逻辑(批 + 流)、数据合并复杂、运维成本高。

2.3.2 Kappa 架构

Kappa 架构由 Jay Kreps 提出,核心思想是只用一套流处理引擎处理所有数据:

  • 所有数据(包括历史数据)都通过消息队列(如 Kafka)以流的形式输入。
  • 流处理引擎(如 Flink)统一处理全量数据,支持数据重放(Replay)以修正错误。
  • 无需独立的批处理层,简化架构。
优点:单一代码逻辑、架构简洁、易于维护。
缺点:对消息队列的存储和重放能力要求高、历史数据重放耗时较长。
对比维度 Lambda 架构 Kappa 架构
处理引擎 批处理 + 流处理(两套) 仅流处理(一套)
代码维护 两套代码(批逻辑 + 流逻辑) 一套代码(流逻辑)
数据一致性 最终一致(需合并批视图与实时视图) 精确一次(流引擎保证)
历史数据重算 批处理层直接重算 消息队列重放(依赖 Kafka 存储)
延迟 批处理延迟高(分钟级),流处理延迟低 统一低延迟(毫秒级)
适用场景 对历史数据完整性要求极高、实时与批处理逻辑差异大 实时性要求高、希望简化架构、消息队列存储充足
实战提示:在批流一体图谱API中,推荐采用 Kappa 架构 作为基础,使用 Flink 统一处理全量历史数据(通过 Kafka 重放)和实时增量数据。仅在需要大规模全量图重建(如 T+1 全量实体关系图)时,引入 Spark 批处理作为补充,形成“Kappa 为主、Lambda 为辅”的混合模式。
Lambda 架构 vs Kappa 架构 Lambda 架构 全量历史数据 批处理层(Spark) 批视图(Batch View) 服务层(合并查询) 实时增量数据 实时增量数据 流处理层(Flink) 实时视图 Kappa 架构 全量 + 增量数据(Kafka) 统一流处理层(Flink) 统一视图(无合并) 服务层(直接查询) Lambda 架构:两套代码 + 合并逻辑;Kappa 架构:一套代码 + 消息队列重放 → 更简洁的批流一体方案

2.4 本章小结

批处理与流处理是批流一体系统的两大基石:

  • 批处理:MapReduce 奠定基础,Spark 通过内存计算和 DAG 优化大幅提升性能,适合全量历史数据重建。
  • 流处理:Storm 提供早期流处理能力,Flink 以事件时间、状态管理和精确一次语义成为现代流处理标准,适合实时增量数据处理。
  • 架构选型:Lambda 架构成熟但复杂,Kappa 架构简洁但依赖消息队列能力。在批流一体图谱API中,推荐以 Kappa 架构为主,必要时引入 Spark 批处理作为补充。
下一阶段:在掌握批流处理基础后,我们将进入图谱数据模型设计,学习如何将实体、关系、属性映射为可被批流引擎高效处理的数据结构。