一、什么是Lambda架构?

想象你正在经营一家电商平台,每天有数百万用户浏览商品、下单支付。这些数据既要实时统计(比如当前热卖商品),又要长期分析(比如季度销售趋势)。Lambda架构就是为解决这类问题而生的——它像一条"双车道高速公路",一条车道处理实时数据(快但可能不够精确),另一条车道处理批量数据(慢但绝对准确),最终在出口处合并结果。

技术栈:Apache Kafka + Apache Spark + Hadoop HDFS

# 示例:用PySpark实现Lambda架构的批处理层(HDFS存储)
from pyspark.sql import SparkSession

spark = SparkSession.builder.appName("BatchLayer").getOrCreate()

# 从HDFS读取历史数据
batch_data = spark.read.parquet("hdfs://batch_data/*.parquet")

# 计算月度销售总额(精确结果)
monthly_sales = batch_data.groupBy("month").sum("amount")

# 将结果写入数据库
monthly_sales.write.jdbc(url="jdbc:mysql://db_host/sales", 
                        table="monthly_stats",
                        mode="overwrite")

二、Lambda架构的三层分工

1. 批处理层(Batch Layer)

相当于系统的"硬盘",存储所有原始数据并用MapReduce等批量计算框架生成全局视图。比如Hadoop每天凌晨跑一次全量计算,虽然延迟高,但数据100%准确。

2. 速度层(Speed Layer)

像是系统的"内存",用Storm/Flink等流处理框架处理最新数据。例如实时统计页面点击量,虽然可能有少量误差,但能秒级响应。

// 示例:用Flink实现速度层(Kafka流处理)
DataStream<ClickEvent> clicks = env
    .addSource(new FlinkKafkaConsumer<>("clicks", new ClickEventSchema(), props));

// 每5秒统计一次点击量
clicks.keyBy("pageId")
      .timeWindow(Time.seconds(5))
      .aggregate(new ClickCounter())
      .addSink(new RedisSink<>());

3. 服务层(Serving Layer)

作为"展示柜",合并前两层的结果供查询。比如Druid数据库既存储批量计算的年度报表,也包含实时更新的当日数据。

三、实际应用案例

某物流公司用Lambda架构实现了这样的系统:

  • 实时层:Kafka收集货车GPS信号,Spark Streaming计算当前位置
  • 批处理层:Hadoop分析历史路线优化配送方案
  • 服务层:将实时位置与优化路线叠加显示在司机APP上
// 示例:合并实时与批量结果(Scala代码)
def mergeResults(realtime: Map[String, Double], batch: Map[String, Double]): Map[String, Double] = {
  // 优先使用批处理结果,实时数据仅作为临时补充
  batch.map { case (k, v) => 
    k -> (v + realtime.getOrElse(k, 0.0)) 
  }
}

四、为什么选择Lambda架构?

优势

  • 容错性强:原始数据永久保存,随时可重算
  • 灵活性高:可单独扩展实时或批量处理能力
  • 技术成熟:已有大量成功案例验证

挑战

  • 需要维护两套代码(批处理和流处理)
  • 最终一致性可能导致短暂数据不一致
  • 对运维团队要求较高

五、新手的注意事项

  1. 数据对齐:确保实时和批量处理使用相同的时间窗口划分
  2. 资源分配:建议批处理层占70%资源,速度层占30%
  3. 监控重点:特别关注两层结果之间的差异值

六、演进与替代方案

现在也有Kappa架构(全流式处理)等新思路,但Lambda架构仍然是很多企业的首选。就像混合动力汽车,内燃机(批处理)和电动机(实时处理)的组合依然是最稳妥的方案。