2. Lakehouse 架构基础:什么是 Lakehouse?

说实话,我第一次听到 Lakehouse 这个词,心里是有点抵触的。那时候数据仓库和数据湖打得火热,突然冒出个新概念,我第一反应是「又是个炒作吧」。

但后来我在一个跨云项目中栽了跟头——数据湖里存了几百 TB 的 Parquet 文件,团队想跑个简单的 BI 报表,结果每次都要全表扫描,跑一次要两小时。数据仓库倒是快,但存不下这么多原始日志,而且跨云同步成本高得吓人。

这时候我才意识到,Lakehouse 不是噱头。它解决了一个很实在的问题:让数据湖拥有数据仓库的事务能力和性能。

2.1 什么是 Lakehouse?

Lakehouse 是一种新的数据架构模式。它把数据湖的廉价存储和数据仓库的 ACID 事务、Schema 强制、索引优化结合在了一起。

你想想看,传统数据湖能存任何格式的数据,成本低,但查询性能差,而且多个任务同时写同一个文件时,数据很容易乱掉。数据仓库性能好、数据一致性强,但存储贵,扩展性有限。

Lakehouse 的核心理念就是:在低成本的对象存储(比如 S3、OSS、ADLS)上,直接构建事务层和查询引擎。不需要把数据搬来搬去。

一句话总结:Lakehouse = 数据湖的存储底座 + 数据仓库的事务与性能能力。

我在一个金融客户的项目里,就用 Lakehouse 架构替换了原来的 Hive + Teradata 方案。存储成本降了 60%,查询性能反而提升了 3 倍。嗯,老板当时看我的眼神都不一样了。

2.2 Lakehouse 的核心组件

Lakehouse 架构由三层组成。我习惯把它想象成一个三明治——每一层各司其职,缺一不可。

2.2.1 存储层

存储层是 Lakehouse 的地基。它通常基于云对象存储,比如 AWS S3、阿里云 OSS、Azure ADLS。

  • 廉价且弹性:按量付费,存 1TB 和存 1PB 只是账单数字的区别。
  • 开放格式:数据以 Parquet、ORC、Avro 等列式格式存储,任何引擎都能读。
  • 不可变性:文件一旦写入就不修改,更新通过新文件 + 元数据指针切换实现。

我的经验:存储层选型时,一定要关注跨云数据迁移的带宽费用。我曾经在 AWS 和 Azure 之间同步数据,一个月账单多了 2 万美金——就因为没算清楚 egress 费用。

2.2.2 元数据层

元数据层是 Lakehouse 的大脑。它管理着哪些文件属于哪个表、哪些数据已提交、哪些还在事务中。

没有元数据层,数据湖就是一盘散沙。你想想看,几百个 Parquet 文件散落在不同目录,你怎么知道哪些是有效的?

元数据层通常由事务日志(Transaction Log)实现。每次数据变更,都会在日志里追加一条记录。查询时,引擎只读取日志中标记为「已提交」的文件。

  • Delta Lake:使用 _delta_log 目录下的 JSON 文件作为事务日志。
  • Apache Iceberg:使用元数据文件(Metadata File)和 Manifest 列表来追踪快照。
  • Apache Hudi:使用 Timeline 机制记录所有操作。

2.2.3 计算层

计算层是执行查询的地方。它可以是 Spark、Presto/Trino、Flink,甚至是 DuckDB。

计算层通过元数据层知道「哪些文件需要读」,然后直接从存储层拉取数据。这种存储与计算分离的设计,让两者可以独立扩缩容。

我做过一个实验:同一个 Delta 表,用 Spark 跑 ETL,用 Trino 跑 Ad-hoc 查询,两者互不干扰。计算资源用完就释放,存储成本不变。这在传统数据仓库里根本做不到。

注意:计算层和存储层之间的网络带宽是瓶颈。跨云查询时,尽量把计算节点部署在离存储最近的区域。我曾经在美东的计算节点查美西的 S3 数据,延迟高了 80 毫秒,整个查询慢了 4 倍。

2.3 Delta Lake 与 Apache Iceberg 对比

这两个是目前最主流的 Lakehouse 表格式。我两个都用过,各有千秋。下面这张表是我在实际项目中的感受总结。

对比维度 Delta Lake Apache Iceberg
起源 Databricks 开源,与 Spark 深度绑定 Netflix 开源,引擎无关设计
事务日志 JSON 文件,存储在表目录的 _delta_log 下 元数据文件 + Manifest 列表,支持多级元数据树
Schema 演进 支持列添加、删除、重命名、类型提升 支持列添加、删除、重命名、类型提升,更灵活
分区演进 不支持修改分区策略(需重建表) 支持分区策略动态变更(Hidden Partitioning)
时间旅行 基于事务日志版本,支持到任意历史版本 基于快照 ID,支持到任意历史快照
跨引擎支持 Spark 为主,Trino/Flink 支持较晚 Spark、Trino、Flink、Hive、Presto 原生支持
优化操作 OPTIMIZE(小文件合并)、Z-Order 排序 Rewrite(文件重写)、Sort Order、Bin Pack
云厂商集成 Databricks 深度集成,AWS 支持好 AWS(Athena/EMR)、Azure、GCP 原生支持

2.3.1 我什么时候选 Delta Lake?

如果你的技术栈以 Spark 为主,团队对 Databricks 生态熟悉,Delta Lake 是更省心的选择。它的 OPTIMIZE 和 Z-Order 优化效果明显,而且事务日志简单易懂。

我曾经在一个实时数仓项目里用 Delta Lake,每天处理 5 亿条事件数据。小文件合并用 OPTIMIZE 跑一次,查询性能提升了 10 倍。嗯,运维同学当时开心得不行。

2.3.2 我什么时候选 Apache Iceberg?

如果你的查询引擎不止一种——比如同时用 Spark 做 ETL、Trino 做 BI、Flink 做实时——Iceberg 的跨引擎兼容性更好。

Iceberg 的 Hidden Partitioning 是个杀手级功能。你不需要手动指定分区字段,Iceberg 会根据数据自动推断。我有个同事因为改分区策略重建了 3 次表,后来换成 Iceberg,再也没为分区头疼过。

我的建议:如果团队 Spark 技术栈深厚,选 Delta Lake;如果追求引擎中立和长期灵活性,选 Iceberg。两个都支持跨云,但 Iceberg 在 AWS 和 GCP 上的原生集成更好一些。

2.4 Lakehouse 架构总览图

下面这张图是我自己画的 Lakehouse 三层架构。你可以看到数据从存储层向上流动,元数据层在中间做「交通指挥」,计算层在顶部执行查询。

Lakehouse 三层架构图 Lakehouse 三层架构 计算层 Spark · Trino · Flink · DuckDB 存储与计算分离,独立扩缩容 元数据层 事务日志 · Schema 管理 · 快照隔离 Delta Lake / Apache Iceberg / Apache Hudi 存储层 AWS S3 · 阿里云 OSS · Azure ADLS Parquet / ORC / Avro 列式存储 元数据层是 Lakehouse 的核心,它让廉价的对象存储拥有了事务能力

2.5 避坑指南

最后分享几个我踩过的坑,希望能帮你少走弯路。

  • 不要迷信「一键迁移」:从 Hive 迁移到 Lakehouse,不是改个表格式就完事了。分区策略、文件大小、压缩格式都要重新调优。我见过一个团队直接迁移,查询比原来还慢。
  • 小文件是性能杀手:流式写入容易产生大量小文件。记得定期跑 OPTIMIZE 或 Rewrite 合并文件。我有个项目因为忘了做这个,查询延迟从 5 秒涨到了 2 分钟。
  • 跨云查询先测网络:不同云厂商之间的网络延迟和带宽差异很大。建议先用 curl 或 iperf 测一下实际吞吐量,再决定计算节点部署位置。
  • 事务日志别乱删:Delta Lake 和 Iceberg 的事务日志是恢复数据的唯一依据。我曾经手滑删了 _delta_log 目录,结果整个表的历史版本全丢了。嗯,那次加班到凌晨三点。

一句话避坑:Lakehouse 不是银弹。如果你的场景是纯 BI 报表且数据量不大,传统数据仓库可能更省心。Lakehouse 的优势在大数据量、多引擎、跨云场景下才能真正体现出来。