1. 实时数仓架构概览:Lambda 与 Kappa 之争,分层职责

大家好,欢迎来到《从 ODS 到 DWD:实时数据清洗实战》的第一章。

做实时数仓这几年,我最大的感触是:架构选型没有银弹。Lambda 和 Kappa 吵了这么多年,说白了就是「批处理」和「流处理」谁当老大的问题。我个人习惯先看业务场景再定架构,而不是拿着锤子找钉子。

1.1 为什么需要实时数仓?

传统离线数仓 T+1 产出,遇到「双十一大屏实时 GMV」「风控秒级拦截」这类场景就抓瞎了。实时数仓的核心目标就一个:降低数据延迟,从小时级降到分钟级甚至秒级。

但注意,实时不等于没有批处理。我在项目中遇到过不少新人,一上来就全盘否定离线,结果实时链路抖动时连个兜底方案都没有。嗯,这里要留个心眼。

1.2 Lambda 架构:批流「两条腿」走路

Lambda 架构是 Nathan Marz 提出的,核心思想是「批处理层 + 速度层 + 服务层」三件套。

层级 职责 典型技术
批处理层 全量历史数据,高吞吐,最终一致 Hive / Spark SQL
速度层 增量实时数据,低延迟,近实时 Flink / Kafka Streams
服务层 合并批+流结果,对外统一查询 Druid / ClickHouse

说白了,Lambda 就是「两条腿走路」——批处理保证全量准确,速度层保证实时新鲜。但代价也很明显:两套代码、两套运维。我曾经在一个项目里维护过三套一样的逻辑(Hive SQL + Flink SQL + 合并逻辑),每次改口径都想骂人。

避坑指南:Lambda 架构中,批处理和速度层的结果合并是最大痛点。我曾经因为时间窗口对齐问题,导致大屏上实时数据比离线数据多出 5%,排查了整整两天。建议在服务层用「覆盖写」策略,以批处理结果为准,速度层只做增量修正。

1.3 Kappa 架构:一切皆流

Kappa 架构是 Jay Kreps 提出的,核心就一句话:用一套流引擎处理所有数据。历史数据通过「重放 Kafka 日志」来重新计算,不再需要批处理层。

你想想看,如果 Kafka 能保存全量日志,Flink 能回溯消费,那为什么还要维护两套代码?Kappa 的优雅之处就在这里——逻辑统一、运维简单。

但现实很骨感。我在实践中发现,Kappa 对 Kafka 的存储压力很大,而且一旦流任务出问题,重跑历史数据的时间成本可能比离线还高。所以我的建议是:中小规模场景(日均百亿条以内)优先考虑 Kappa,大规模场景还是 Lambda 更稳。

我的选择标准:
  • 数据量 < 100 亿条/天,实时性要求秒级 → Kappa
  • 数据量 > 100 亿条/天,需要全量回溯 → Lambda
  • 团队只有 3-5 人,不想维护两套代码 → Kappa
  • 业务对准确性要求极高(如金融交易) → Lambda + 离线校验

1.4 实时数仓分层:ODS、DWD、DWS、ADS

不管用 Lambda 还是 Kappa,分层思想是通用的。我习惯把实时数仓分成四层,每一层解决一个核心问题。

实时数仓分层架构图 ODS 层(操作数据存储) 原始数据接入,保持原样,不做任何清洗 DWD 层(明细数据层) 数据清洗、去重、维度退化、格式统一 DWS 层(汇总数据层) 轻度汇总,按主题宽表聚合,预计算指标 ADS 层(应用数据层) 面向业务应用,大屏、报表、接口直接使用 数据流向:ODS → DWD → DWS → ADS,层层递进,逐层降维

ODS 层:原始数据缓冲区

ODS 就是「数据的」。Kafka 里来什么,我就存什么,不做任何清洗。为什么?因为一旦清洗逻辑出错,原始数据就丢了,想重跑都没机会。

我在项目中习惯给 ODS 层设置 7 天的 Kafka 保留期,配合 HDFS 冷备份。这样既保证实时回溯,又兼顾成本。

DWD 层:清洗核心战场

这是本课程的重点。DWD 层要做的事情包括:

  • 去重:用 Flink 的 Deduplication 或 Kafka 的幂等写入
  • 维度退化:把维表字段直接拉平到事实表
  • 格式统一:时间戳转标准格式,枚举值转编码
  • 脏数据过滤:空值、异常值、乱码数据直接丢弃或发到死信队列
小技巧:DWD 层的数据量通常是 ODS 的 60%-80%。如果发现清洗后数据量反而变大,八成是维表拉平导致字段膨胀,或者去重逻辑有 bug。我遇到过因为去重窗口设置太小,导致重复数据流入下游,大屏指标直接翻倍的情况。

DWS 层:预聚合加速

DWS 层说白了就是「提前算好」。比如按分钟、小时、天预聚合 PV/UV、GMV、转化率等指标。这样 ADS 层查询时就不用再扫全量明细了。

我建议 DWS 层使用 Flink 的 Tumble Window + 状态后端(RocksDB),窗口大小根据业务需求灵活调整。注意状态大小控制,我曾经因为窗口状态太大导致 Checkpoint 超时,整个任务重启了三次。

ADS 层:面向应用

ADS 层是给业务看的。大屏、报表、数据接口直接读这一层。数据一般存在 ClickHouse、Doris 或 Redis 中,要求查询延迟在毫秒级。

这里有个坑:不要把所有指标都塞到 ADS 层。我见过一个项目,ADS 层一张表 200 个字段,查询时只用到 5 个,白白浪费存储和计算资源。建议按业务主题拆分,比如「交易主题」「用户主题」「流量主题」各建一张表。

1.5 Lambda vs Kappa:我到底该选哪个?

直接上对比表,大家按需取用:

对比维度 Lambda 架构 Kappa 架构
代码维护 两套代码(批+流) 一套代码(流)
数据准确性 高(批处理兜底) 中(依赖流引擎容错)
实时性 秒级(速度层) 秒级
历史回溯 快(直接跑批) 慢(重放 Kafka 日志)
运维复杂度 高 低
适用场景 金融、电商大促、对账 日志分析、监控、推荐

我个人习惯是:新项目优先 Kappa,等业务规模上来后再考虑是否引入批处理层做 Lambda。毕竟架构演进是动态的,没必要一开始就上重武器。

本章小结:
  • Lambda 架构:批流分离,准确但复杂
  • Kappa 架构:一切皆流,简单但有局限
  • ODS 层:原始数据,不动
  • DWD 层:清洗核心,去重+维度退化+格式统一
  • DWS 层:预聚合,加速查询
  • ADS 层:面向应用,直接输出