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 + 合并逻辑),每次改口径都想骂人。
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 层:原始数据缓冲区
ODS 就是「数据的」。Kafka 里来什么,我就存什么,不做任何清洗。为什么?因为一旦清洗逻辑出错,原始数据就丢了,想重跑都没机会。
我在项目中习惯给 ODS 层设置 7 天的 Kafka 保留期,配合 HDFS 冷备份。这样既保证实时回溯,又兼顾成本。
DWD 层:清洗核心战场
这是本课程的重点。DWD 层要做的事情包括:
- 去重:用 Flink 的 Deduplication 或 Kafka 的幂等写入
- 维度退化:把维表字段直接拉平到事实表
- 格式统一:时间戳转标准格式,枚举值转编码
- 脏数据过滤:空值、异常值、乱码数据直接丢弃或发到死信队列
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 层:面向应用,直接输出