从数据湖到 Lakehouse:Databricks 的架构演进给行业带来了什么启示

本文深度解读从数据湖到Lakehouse的演进逻辑,分析Databricks如何用Delta Lake实现事务能力,如何通过Databricks SQL优化查询性能,并对比数据湖、数仓和湖仓一体三种架构的取舍,给出实际落地时的工程建议与避坑思路。

大概两年前,当我们把核心报表任务从 Hive 迁移到 Spark 上时,一度以为把数仓搬到数据湖是一场彻底的升级。后来才发现,问题并没有因为“搬到湖边”而自动消失,反而在湖上失去了原本在仓库里习以为常的保障。这也是 Databricks 提出 Lakehouse 之后,我一直想理清的一个问题:一个既能装下原始数据、又能承担起企业级查询和 BI 的平台,到底应该长什么样?这篇文章想从数据湖到 Lakehouse 的演进路径出发,结合 Databricks 的实际做法,聊聊湖仓一体对于数据平台建设究竟意味着什么。

AI technology illustration

数据湖为什么被追捧,又为什么让人头疼

数据湖这个概念本身的吸引力很直接:存储成本低,格式灵活,几乎所有类型的数据都能往里放。很多团队第一步是拿它来做探索性分析和机器学习,因为模型实验需要自由地访问原始数据,而不是经过重重加工后的汇总表。但正如许多实践者很快发现的那样,数据湖的“自由”是有代价的。它没有事务控制,写入任务失败到一半,下游可能读到残缺数据;它缺少统一的元数据管理,业务组之间各自建表,同一个字段在不同表里可能含义完全不同;它的查询性能也远不稳定,一个多表关联在数仓里几秒钟能出的结果,在湖上可能要跑十分钟。

一个典型的场景是:推荐系统团队白天往湖里灌埋点日志,晚上跑统计指标,凌晨再更新模型的特征数据。这套流程里,特征表需要被反复覆盖。因为没有事务保证,覆盖过程一旦出现异常,表就会处于中间状态,甚至会把空文件留在那里,导致后续训练任务拿到的是不完整的数据。这类问题的特征是“偶尔出现、很难复现”,排查起来非常耗时。时间一长,业务团队就会开始绕过平台团队,直接读原始文件,自己算口径。于是同一个指标,不同部门算出来的数对不上,数据治理变得举步维艰。

面对这些问题,最稳妥的选择是回到数据仓库。但数据仓库自己也有一堆不舒服的地方:硬件成本高,schema 限制严格,数据加载模式固定,扩展性通常依赖昂贵的商用 MPP 引擎。更关键的是,很多企业的数据模型还在持续调整,数仓的建模周期往往跟不上业务变化。所以真正的需求并不是“仓库好还是湖好”,而是能不能在低成本存储上,同时获得数仓的事务性、一致性和查询性能。这正是 Lakehouse 架构试图回答的问题。

Delta Lake:给数据湖装上事务层

Databricks 的做法没有把数据湖推倒重来。他们在原有数据湖的文件层之上,加了一个事务性中间层,这就是 Delta Lake。Delta Lake 并不是一种全新的文件系统,而是基于原来就常见的 Parquet 文件,增加了一套事务日志。每次操作——无论是写入、修改还是删除,都会先在日志里记录一条原子动作,然后系统根据日志决定当前表的数据快照。这样,数据湖里的表就具备了 ACID 事务、可重复读快照以及版本回滚能力。

有了这一层,许多之前很难实现的场景就变得顺理成章了。比如流式数据与批处理数据的合并,可以用一个 merge 操作完成,而不需要手动写多个脚本去删文件和插入新数据。下面这段代码展示的是典型的 upsert 操作:

from pyspark.sql import SparkSession
from delta.tables import DeltaTable

spark = SparkSession.builder.getOrCreate()
updates_df = spark.read.parquet('/events/2024/05/01')

(DeltaTable.forPath(spark, '/warehouse/dwd_events')
    .alias('target')
    .merge(updates_df.alias('source'), 'target.event_id = source.event_id')
    .whenMatchedUpdateAll()
    .whenNotMatchedInsertAll()
    .execute())

在数据湖时代,这样的 merge 实现往往需要配合 Hadoop 文件操作,一致性还得不到保证。而在 Delta Lake 中,它成为一个原子操作,任务成功与否,下游都只会看到一致的数据状态。除了事务,Delta Lake 还提供 schema 演化和 time travel,也就是说,即使表结构悄悄变化,历史查询也能通过快照继续执行。这些能力让“湖”真正具备了一部分“仓”的配置和治理基础。

Databricks SQL:让分析师也能在湖上跑报表

光有存储层的事务支持还不够,查询性能和用户体验同样关键。Databricks 早期依托 Spark 实现分布式计算,但 Spark SQL 在交互式查询上一直被认为不够快。随后,Databricks 推出了 Databricks SQL(也就是后来的 SQL Analytics),并且为它构建了名为 Photon 的向量化执行引擎。Photon 重新实现了 Spark SQL 的执行层,目标是让查询接近传统数仓的响应速度,同时仍然可以跑在廉价的云存储之上。

换句话说,Databricks 并没有简单地把 Spark 原样作为一个 SQL 引擎抛给大数据团队。他们花大量精力优化了分布式的查询计划、列式存储的读取方式以及 shuffle 的缓存机制。站在用户视角,分析师可以用标准 SQL 直接查询湖上的数据,甚至可以直接链接 BI 工具,体验上越来越像一个数仓。与此同时,数据科学家依然可以用 Python、Scala 或 R 访问同一份数据。这也就是 Lakehouse 架构的核心形态:一个存储,多种计算引擎,互为补充。

架构对比:数据湖、数仓与 Lakehouse 的取舍

要理解 Databricks 在湖仓一体上的位置,最有用的方式是直接对比三种架构的差异。以下是从实际选型中总结出来的一些维度:

对比维度 传统数据湖 企业数据仓库 Lakehouse
存储成本
数据格式 任意文件 预定义 schema 文件 + 事务日志
事务能力 无或弱 表级 ACID
查询性能 依赖计算引擎,通常一般 优秀 通过索引和缓存接近数仓
数据治理 困难 完善 基于 Catalog 与格式层治理
典型负载 机器学习、探索性分析 BI 报表、审计 BI + ML + 流式混合负载

这张表并不是说 Lakehouse 全面优于其他架构,而是说明它放在了一个二维空间里:既想在成本策略和数据灵活性上贴近数据湖,又想在一致性、事务和查询性能上贴近数仓。但获得的每一点优势,都需要在工程实现上付出代价,比如存储层越发复杂,需要引入新的运维和调优能力。

落地 Lakehouse 时容易踩的坑

理论上看,Lakehouse 似乎很理想。但真正在生产环境跑起来,很多 Databricks 用户也会遇到自己独特的问题。这里我想重点聊几个容易被忽视的坑。

首先是小文件问题。由于流式任务不断写入,Delta 表会积累大量小 Parquet 文件。未及时合并时,查询引擎需要打开大量文件,性能反而比直接从原始文件读还差。Databricks 提供了 OPTIMIZE 命令来做文件压缩,但什么时候做、以什么频率做、压缩期间是否影响查询,这些都需要根据你的写入速率和查询负载来设置。我曾经见到一个团队,把每五分钟的流数据都落成独立分区,结果一张表上有几万个小文件,任何查询都被拖垮了。

第二个坑是并发写冲突。Delta Lake 通过乐观并发控制来实现事务,但当多个任务同时写同一个表时,仍会遇到版本冲突。如果一个批处理任务和一个流式任务在同一个时间窗口内写同一张表,其中一个任务会失败并需要重试。严格来说,这其实是一个设计初衷:宁可让一个任务失败,也不能让数据不一致。但在生产环境里,如果你没有设计好写入频率和分区策略,这样的失败会频繁出现,阻碍业务连续性。

第三个坑是对 schema 迁移的误读。很多文章神化了 Delta Lake 的 schema evolution,以为表结构随便演变都没关系。实际上,schema 演进只解决读取兼容性,不解决业务语义的变化。上游字段改了含义,下游模型不会因为你做了自动的 schema 合并就自动适应。如果你没有先在元数据层对齐口径,那么这份数据迁移到 Lakehouse 上依然是一团乱麻。

我们可以把这些经验总结成几个关键点。

  • 做文件压缩和 Z-ORDER 索引,需要像调优数仓一样看待存储文件结构。
  • 写入冲突不可怕,但要设计好任务优先级和重试机制。
  • schema 演进是系统能力,但业务对齐依然是团队职责。
  • Catalog、权限、数据血缘,需要从一开始就治理起来。

Databricks 架构演进带给行业的启示

Databricks 并不是第一个提出湖仓一体化概念的公司,但它是这个方向上最具代表性的推动者之一。从它公开的架构资料和技术落地来看,真正的启示并不在于 Delta Lake 这个文件格式,而在于它对数据平台分层方式的重塑。

首先是存储与计算的彻底解耦。传统数仓往往将存储和计算绑定在一起,扩展计算会牵连存储,迁移数据往往增加成本。Lakehouse 在对象存储上统一目录,计算层可以弹性伸缩,两者都能独立演进。这让大数据平台第一次在公有云上拥有了更接近普通数据库的灵活性。

其次,数据治理开始下沉到存储层。数仓的治理能力通常依赖专用的元数据服务和复杂的 ETL 流程,而 Lakehouse 通过在存储格式层内建事务日志和 schema 信息,让同一份文件在写入时就能被治理。这个方向的演化,意味着很多曾经只能靠人工操作保证的数据质量,现在开始可以被系统自动捕获。

最后,它是从开源生态长出来的商业价值。Delta Lake 已经有开源版本,但 Databricks 在它之上附加了优化和粘合,形成了托管服务。这提示整个行业,纯开源的存储很难单独支撑企业级服务,最终需要有人负责性能优化、可靠性保障和完整的客户体验。

当然,Lakehouse 也并不是所有场景的最佳答案。如果你的团队规模不大,但是业务高度依赖结构化的预定义报表,团队里又缺少 Spark 或分布式系统的人才,那直接选择云数据仓库依然是最稳的路径。反过来,如果你的数据形态复杂、机器学习权重高、希望打破数据孤岛,那么 Lakehouse 能带来的价值会非常明显。任何架构选择都要基于自身的约束和路线图,不能因为厂商的宣传而左右摇摆。

如果你正打算启动 Lakehouse 迁移,我的建议是不要从核心数仓搬起。先去选一个探索性业务或者一个高频变更的数据域,把原始数据同步到湖上,再在它之上建一个小的 Delta 表,用你熟悉的 BI 工具去查询。等这些场景稳定运行后,再考虑把更多报表逻辑迁过来。宁可让初期迁移范围小一点,也要把存储治理、权限控制和自动化任务调度跑通。

最后说几句

从数据湖到 Lakehouse,Databricks 的演进其实映射了整个数据平台的一个深层变化:我们不再把“湖”和“仓”看作两个非此即彼的阵营,而是把它们的能力融合成一个可以按需组合的体系。这个体系强调低成本的存储、灵活的计算,以及企业级的数据管理。谁能够先把这三者平衡好,谁就能在数据驱动上走得更远。

技术名词的更新速度越来越快,但真正有长期价值的,永远是背后那些围绕成本、性能、治理做出的取舍。也许 Lakehouse 这个名字未来会被其他概念取代,但我们已经从中学到的一个重要经验是:不能为了技术先进性而放弃数据平台的基本纪律,也不能因为守旧而不去重新思考传统方案中的不合理开销。架构演进的意义,不在于换上最新的名字,而在于更清晰地理解每一层需要承担什么责任。

原创文章,作者:fudengji,如若转载,请注明出处:https://fudengji.cn/article/986/

(0)
上一篇 1小时前
下一篇 1小时前

相关推荐