数据仓库架构演进:从传统到湖仓一体

大家好,我是老周。今天咱们聊聊数据仓库架构的演进史。说实话,我入行那会儿,哪有什么Lambda、Kappa,能跑通一个ETL流程就算高手了。但技术这东西,迭代得真快。你想想看,从Ingres到Snowflake,也就二十来年,架构思路已经翻了好几番。

这一章,我会结合自己踩过的坑,把传统数仓、Lambda、Kappa、云原生数仓和湖仓一体这五个阶段掰开揉碎讲清楚。嗯,咱们开始吧。

一、传统数仓架构:Ingres与Informatica时代

90年代末到2000年初,企业做数仓基本就两件套:Ingres(或Oracle/Teradata)做存储,Informatica(或DataStage)做ETL。那时候的架构长这样:

传统数仓架构(Ingres + Informatica) 业务系统(OLTP) 日志文件 / CSV 外部数据源 Informatica / DataStage ETL Ingres / Oracle / Teradata 数仓 报表 / BI / 数据应用

这个架构的核心逻辑很简单:ETL抽数据 → 清洗转换 → 加载到数仓 → 出报表。我当年在电信公司做项目,每天凌晨跑批处理,几十张表关联,跑完差不多天亮了。那时候最怕的就是ETL跑崩,一崩就是半天。

传统数仓的特点:

  • 批处理为主:T+1延迟,今天只能看昨天的数据
  • Schema-on-Write:数据入库前必须定义好模型
  • 扩展性差:扩容要加硬件,成本高
  • 实时能力弱:基本不支持流式处理

我的经验:如果你现在还在用传统架构做新项目,建议慎重。除非业务对实时性完全没要求,且数据量可控(TB级以内)。否则,Lambda或云原生会是更好的选择。

二、Lambda架构:批流分离的妥协方案

到了2010年左右,大家发现传统数仓扛不住实时需求了。比如电商大促,你总不能等第二天再看实时销量吧?于是Nathan Marz提出了Lambda架构。

Lambda的核心思路是:批处理层 + 速度层 + 服务层。批处理层负责全量历史数据,保证准确性;速度层负责实时增量数据,保证低延迟;服务层把两者合并,对外提供统一视图。

Lambda 架构 实时数据流 批处理层(Batch Layer) Spark / Hive / MapReduce 速度层(Speed Layer) Storm / Flink / Kafka Streams 主数据集(Master Dataset) 实时视图(Realtime View) 服务层(合并查询)

我曾经踩过的坑:Lambda架构最大的问题是维护两套代码。批处理和流处理逻辑要分别实现,而且结果还得对得上。我有个项目,批处理用Spark,流处理用Flink,同样的业务逻辑写了两遍,调试时发现两边聚合结果差了0.5%。查了三天,原来是时间窗口的边界处理不一致。嗯,从那以后我对Lambda就有点心理阴影了。

Lambda的优点很明显:兼顾实时和历史。但缺点也突出:

  • 代码重复:批和流两套逻辑,维护成本翻倍
  • 数据一致性难保证:批处理和流处理结果可能对不上
  • 架构复杂:组件多,运维压力大

三、Kappa架构:简化,再简化

既然Lambda这么麻烦,那能不能只用一套流处理搞定所有?2014年,Jay Kreps提出了Kappa架构。说白了,就是一切皆流。

Kappa的核心思想:所有数据都走实时流处理,历史数据重放也通过流来实现。你想想看,如果Kafka能保存全量数据,那批处理不就是流处理的一种特殊情况吗?

Kappa架构的关键组件:

  • 消息队列(Kafka):统一数据入口,保存全量日志
  • 流处理引擎(Flink/Spark Streaming):一套代码处理所有数据
  • 服务层数据库:对外提供查询

我去年帮一家金融科技公司做风控数仓,就用了Kappa架构。Kafka存7天数据,Flink做实时特征计算,结果直接写Elasticsearch。延迟控制在秒级,而且代码只有Lambda方案的一半。不过要注意,Kappa对Kafka的存储和吞吐要求很高,磁盘预算得留足。

我的建议:如果业务场景以实时为主,历史数据重放需求不多,Kappa是首选。但如果需要频繁回溯几个月甚至几年的数据做全量重算,Lambda可能更合适——毕竟Kafka存全量数据的成本不低。

四、云原生数仓:Snowflake与Redshift

2015年以后,云计算彻底改变了数仓的玩法。以Snowflake和Amazon Redshift为代表的云原生数仓,把「存算分离」做到了极致。

特性 Snowflake Redshift
架构 存算分离,多集群共享存储 存算分离(RA3),节点绑定
弹性 秒级扩缩容,按秒计费 分钟级扩缩容,按小时计费
并发 多Warehouse独立扩展 WLM队列管理
数据格式 自研列式存储,自动优化 列式存储,需手动Sort Key
生态 支持半结构化数据(JSON/Avro) 通过Spectrum支持外部表

我个人特别喜欢Snowflake的一点:计算和存储完全解耦。你可以在一个虚拟仓库跑ETL,另一个跑BI查询,互不干扰。而且Snowflake的「Time Travel」功能,能让你回到任意时间点查数据——这个在数据恢复时太香了。

注意:云原生数仓虽然方便,但成本控制是个坑。我见过一个团队,Snowflake的虚拟仓库忘了关,周末跑了48小时,账单直接多出两万美金。所以,一定要设置自动暂停策略,比如空闲5分钟自动挂起。

五、湖仓一体(Lakehouse):数据湖+数据仓库的融合

最后聊聊湖仓一体。这个概念由Databricks在2020年提出,核心思路是:在数据湖上直接实现数仓的ACID、Schema和性能优化能力。

说白了,以前数据湖存原始数据(JSON、Parquet、Avro),数仓存结构化数据,中间还得靠ETL搬来搬去。湖仓一体把这两层合并了:底层是对象存储(S3/ADLS/OSS),上层通过Delta Lake/Apache Iceberg/Apache Hudi提供事务、索引和版本管理。

湖仓一体(Lakehouse)架构 对象存储(S3 / ADLS / OSS) Parquet / ORC / Avro 文件 表格式:Delta Lake / Iceberg / Hudi 计算引擎:Spark / Presto / Flink / Trino

湖仓一体的核心能力:

  • ACID事务:支持并发读写,不会读到脏数据
  • Schema演进:加列、改类型不用重写全表
  • 时间旅行:查询历史版本数据
  • 统一存储:结构化、半结构化、非结构化数据共存
  • 开放格式:Parquet/Iceberg是标准格式,不会被厂商锁定

我最近在做一个物联网项目,传感器数据既有结构化指标(温度、湿度),又有非结构化日志(设备状态描述)。用湖仓一体,所有数据直接入湖,Spark做批处理,Flink做流处理,Presto做即席查询——一套存储,多引擎共享。这在以前,至少得搭两套系统。

我的判断:湖仓一体是未来五到十年的主流方向。如果你现在要新建数仓,建议优先考虑Lakehouse方案。但要注意,湖仓一体对运维能力要求更高——表格式的版本管理、小文件合并、分区优化,这些都需要专人维护。

小结:怎么选?

好了,五种架构都聊完了。我最后给个选型建议:

  • 传统数仓:别用了,除非你还在维护老系统
  • Lambda:适合批处理和实时需求都很重,且团队有能力维护两套代码的场景
  • Kappa:适合以实时为主,历史数据重放需求少的场景
  • 云原生数仓:适合中小团队,不想操心运维,预算充足
  • 湖仓一体:适合数据量大、数据类型多、需要统一存储和灵活计算的场景