2. Lakehouse 核心概念:数据湖与数据仓库的融合

好,咱们进入第二章。这一章要聊的,是整个 Lakehouse 架构的根基——数据湖和数据仓库到底怎么融合?说白了,就是要把数据湖的灵活性和数据仓库的可靠性捏到一块儿。

我最早做数据平台的时候,团队还在纠结“到底用湖还是用仓”。后来发现,这不是二选一的问题。你想想看,业务部门既要海量原始数据做探索,又要报表数据保证一致性,一个方案解决不了所有问题。所以 Lakehouse 这个思路就出来了——把湖的廉价存储和仓的 ACID 事务结合起来。

2.1 数据湖 vs 数据仓库:核心差异

先看一张对比表,把两者的区别理清楚。我在项目中见过不少团队,把数据湖当仓库用,结果数据质量一塌糊涂。

维度 数据湖 数据仓库
数据格式 原始格式(JSON、CSV、Parquet 等) 结构化、Schema-on-Write
事务支持 无或弱(最终一致性) 强 ACID 事务
更新能力 追加为主,更新困难 支持 UPDATE/DELETE
适用场景 数据探索、机器学习、原始日志 BI 报表、固定查询、数据治理
存储成本 低(对象存储为主) 高(专用存储引擎)

这张表你看完应该能明白,数据湖的优势是“便宜、能装”,但缺点也很明显——数据写进去之后,想改个字段都费劲。数据仓库正好相反,贵但靠谱。

核心观点:Lakehouse 不是要消灭数据湖或数据仓库,而是把两者的优点组合起来。湖提供存储底座,仓提供事务和查询能力。

2.2 融合的关键:事务层

那怎么融合呢?关键就在“事务层”。数据湖本身没有事务能力,但我们可以加一层元数据管理,让湖上的文件操作具备原子性和隔离性。

我个人习惯把 Lakehouse 的架构分成三层:

  1. 存储层:对象存储(S3、ADLS、OSS),存 Parquet/ORC 文件。
  2. 事务层:管理文件版本、事务日志、Schema 演化。
  3. 查询层:Spark、Presto、Flink 等引擎,读取事务层提供的快照。

事务层就是 Delta Lake 和 Iceberg 这类工具干的事。它们给数据湖装上了“版本控制”和“事务日志”,让湖上的数据操作变得像数据库一样可靠。

一个小技巧:刚开始接触 Lakehouse 时,别急着上复杂架构。先用 Delta Lake 或 Iceberg 管理一张表,跑通“读-写-更新”流程,感受一下事务层带来的变化。

2.3 Delta Lake 简介

Delta Lake 是 Databricks 开源的项目,也是 Spark 生态里最成熟的 Lakehouse 方案。它的核心设计是 事务日志(Transaction Log),记录每次对表的操作。

举个例子,你往 Delta 表里插入一批数据,Delta Lake 会做三件事:

  • 把数据写成 Parquet 文件存到存储层。
  • 在事务日志里追加一条记录,说明“新增了哪些文件”。
  • 查询时,只读取日志里最新的文件列表。

这样做的好处很明显——如果写入中途失败,日志里没有提交记录,查询就看不到脏数据。这就是 ACID 的原子性。

我记得有一次,生产环境的数据管道因为网络抖动中断了。如果用普通数据湖,那批半拉子数据就留在那了,后续查询全乱套。但 Delta Lake 的事务日志自动回滚了未提交的操作,数据完整性一点没受影响。

2.3.1 Delta Lake 的核心特性

特性 说明
ACID 事务 支持并发读写,保证数据一致性
Schema 演化 可以动态增删字段,不用重建表
时间旅行 查询历史版本的数据,用于回溯或审计
数据版本控制 每次操作生成一个新版本,可回滚

注意:Delta Lake 的事务日志默认存储在表目录下的 _delta_log 文件夹里。如果误删了这个文件夹,整个表就废了。我曾经见过有人手滑删了日志目录,结果只能从备份恢复。所以,一定要给事务日志目录设置权限保护。

2.4 Apache Iceberg 简介

Apache Iceberg 是另一个主流的事务层方案,由 Netflix 和 Airbnb 等公司贡献。它的设计思路和 Delta Lake 类似,但更强调 表格式的标准化 和 多引擎兼容。

Iceberg 的核心也是事务日志,但它把元数据分成了三层:

  • 元数据文件(Metadata File):记录表的 Schema、分区信息、快照列表。
  • 清单列表(Manifest List):每个快照对应的文件清单。
  • 清单文件(Manifest):具体的数据文件路径和统计信息。

这种分层设计让 Iceberg 在查询时能快速过滤掉不相关的文件。比如你查某一天的数据,Iceberg 通过清单里的统计信息,直接跳过其他分区的文件,性能提升很明显。

我个人的经验是,如果你的团队用 Spark 为主,Delta Lake 上手更快;如果你们有多引擎需求(比如 Spark 写、Presto 读、Flink 流处理),Iceberg 的兼容性更好。

2.4.1 Iceberg 的核心特性

特性 说明
隐藏分区 自动根据数据值计算分区,用户不用手动指定
快照隔离 每个查询基于一个快照,读写互不干扰
Schema 演化 支持列添加、删除、重命名,不重写数据
多引擎支持 Spark、Flink、Trino、Hive 等都能读

2.5 Delta Lake vs Iceberg:怎么选?

这个问题我经常被问到。说实话,没有的答案,但可以给你一些参考:

对比维度 Delta Lake Apache Iceberg
生态绑定 与 Spark 深度集成 引擎无关,兼容性更广
事务日志 JSON 格式,存储在表目录 分层元数据,独立管理
性能优化 Z-Order 排序、文件合并 隐藏分区、文件剪枝
社区活跃度 Databricks 主导,更新快 Apache 基金会,厂商中立

我的建议:如果你们公司已经重度使用 Databricks 或 Spark,选 Delta Lake 更省心。如果你们有多引擎、多云的需求,或者希望避免厂商锁定,Iceberg 是更稳妥的选择。

2.6 核心架构图:Lakehouse 事务层

下面这张图展示了 Lakehouse 的核心架构,重点看事务层怎么连接存储和查询。

Lakehouse 核心架构:事务层 存储层 对象存储(S3 / ADLS / OSS) · Parquet / ORC 文件 事务层 Delta Lake 事务日志 / Iceberg 元数据层 ACID 事务 · Schema 演化 · 时间旅行 · 版本控制 文件合并 · 隐藏分区 · 快照隔离 查询层 Spark · Presto / Trino · Flink · Hive 说明:事务层是 Lakehouse 的核心,它让数据湖具备了数据仓库的事务能力,同时保留了存储层的低成本优势。

2.7 避坑指南:我踩过的几个坑

最后分享几个实战中容易踩的坑,希望能帮你少走弯路。

  • 事务日志膨胀:Delta Lake 和 Iceberg 的日志文件会随着操作次数增加而变大。我曾经遇到过一张表操作了上万次,日志文件比数据文件还大。解决办法是定期执行 VACUUM 清理过期日志。
  • 小文件问题:频繁的流式写入会产生大量小文件,影响查询性能。我建议设置 OPTIMIZE 或 COMPACT 任务,定期合并小文件。
  • Schema 演化冲突:多个任务同时修改表 Schema 可能导致冲突。最好统一管理 Schema 变更,避免并发操作。
  • 版本回滚风险:时间旅行虽然方便,但回滚到旧版本会丢失之后的所有变更。回滚前一定要确认没有其他任务依赖当前版本。

一个小建议:刚开始用 Delta Lake 或 Iceberg 时,先在测试环境跑通所有操作流程。特别是事务日志的清理策略和文件合并策略,一定要根据数据量提前规划好。