4. 数据湖与数据仓库:从对立到融合
聊到AI数据底座,数据湖和数据仓库是两个绕不开的概念。很多新人容易搞混,甚至觉得它们是对立的。其实不然。我个人的理解是:它们解决的是不同阶段的问题,而现在的趋势是把它们结合起来。
4.1 数据仓库:先有结构,再存数据
数据仓库的概念诞生得很早。它的核心思想是 Schema-on-Write——在数据写入之前,先定义好表结构。
你想想看,传统的关系型数据库里,你要先建表,定义字段类型、长度,然后才能往里插数据。数据仓库也是类似的思路,只不过它专门为分析查询做了优化。
- 结构化数据为主:来自业务系统(ERP、CRM)的表格数据
- ETL 清洗:数据入库前要经过抽取、转换、加载
- 高性能查询:针对聚合、关联查询做了列式存储和索引优化
- 数据一致性高:支持事务,保证 ACID
我在项目中遇到过一个问题:业务方想分析用户行为日志,但日志是半结构化的 JSON,数据仓库的 Schema-on-Write 模式要求先定义好所有字段。结果就是,每次日志格式一改,就要改表结构,非常痛苦。
4.2 数据湖:先存数据,再定结构
数据湖的出现,就是为了解决上面那个痛点。它的核心思想是 Schema-on-Read——先把原始数据存下来,等你要用的时候再定义结构。
说白了,数据湖就是一个巨大的存储池。你可以往里扔任何格式的数据:CSV、JSON、Parquet、图片、视频……它不关心你存的是什么,只负责把文件存好。
| 对比维度 | 数据仓库 | 数据湖 |
|---|---|---|
| 数据格式 | 结构化 | 结构化 + 半结构化 + 非结构化 |
| 写入模式 | Schema-on-Write | Schema-on-Read |
| 存储成本 | 较高(需要预处理) | 较低(直接存原始数据) |
| 数据质量 | 高(经过清洗) | 低(原始数据可能有脏数据) |
| 典型场景 | BI 报表、固定指标 | 数据探索、机器学习 |
4.3 湖仓一体:取长补短
数据仓库太死板,数据湖太混乱。那能不能把两者的优点结合起来?这就是湖仓一体(Lakehouse)架构的出发点。
湖仓一体的核心思路是:在数据湖的廉价存储上,实现数据仓库的事务性和查询性能。
我画了一张图,帮你理解这个架构:
你看,湖仓一体就是在廉价的对象存储上,加了一层「表格式层」。这一层负责管理文件的元数据、事务、版本,让底层的一堆 Parquet 文件看起来像一个数据库表。
4.4 Delta Lake:Databricks 的答案
Delta Lake 是 Databricks 开源的存储层框架。它基于 Parquet 格式,在文件层面增加了事务日志。
我记得第一次用 Delta Lake 时,最惊艳的功能是 时间旅行(Time Travel)。你可以查询某个表在任意历史时间点的快照,这对于数据回滚和审计非常有用。
- ACID 事务:支持并发读写,保证数据一致性
- Schema 演进:可以自动或手动修改表结构
- 时间旅行:查询历史版本数据
- 数据版本管理:每个操作都记录在事务日志中
- 小文件合并:自动优化小文件问题
来看一个简单的 Delta Lake 操作示例:
# 写入数据到 Delta 表
df.write.format("delta").mode("overwrite").save("/data/events")
# 读取历史版本(时间旅行)
spark.read.format("delta")
.option("versionAsOf", 5)
.load("/data/events")
# Schema 演进:自动添加新列
df.withColumn("new_col", lit(1))
.write.format("delta")
.option("mergeSchema", "true")
.mode("append")
.save("/data/events")
VACUUM 清理过期版本,但要注意保留足够的历史版本用于回滚。
4.5 Apache Iceberg:开放的表格式标准
Apache Iceberg 是另一个流行的开放表格式。它和 Delta Lake 的目标类似,但设计理念有些不同。
Iceberg 的核心设计是 表格式规范。它定义了一套标准的元数据文件结构,任何计算引擎只要实现了这个规范,就能读写 Iceberg 表。
| 对比维度 | Delta Lake | Apache Iceberg |
|---|---|---|
| 发起方 | Databricks | Netflix(后捐给 Apache) |
| 存储格式 | Parquet(默认) | Parquet / ORC / Avro |
| 事务机制 | 事务日志(JSON) | 快照文件 + Manifest 列表 |
| 分区演进 | 不支持动态修改分区 | 支持分区变换(Partition Evolution) |
| 隐藏分区 | 不支持 | 支持(自动从数据推导分区) |
| 引擎兼容 | Spark、Flink、Presto | Spark、Flink、Trino、Hive、Dremio |
Iceberg 有一个很酷的特性叫 隐藏分区(Hidden Partitioning)。你不需要手动指定分区字段,Iceberg 会根据查询条件自动推导分区。比如你按时间分区,查询 WHERE date = '2024-01-01',它会自动定位到对应的分区文件。
4.6 如何选择:场景决定技术
说了这么多,到底该用哪个?我总结了一个简单的决策流程:
- 纯 BI 报表场景:传统数据仓库(如 Snowflake、Redshift)仍然是最佳选择
- 数据湖 + 部分分析:用 Delta Lake 或 Iceberg 搭建湖仓一体
- 多引擎混合查询:优先 Iceberg,兼容性最好
- 机器学习 + 数据分析:湖仓一体 + 开放表格式
- 实时流处理:关注 Hudi(另一个表格式,擅长增量写入)
嗯,这里要注意:没有银弹。我见过不少团队盲目追求新技术,结果把简单问题复杂化了。如果你的数据量不大(TB 级以下),传统数据仓库完全够用,没必要上湖仓一体。