1. Delta Lake 前世今生

大家好,我是这次课程的主讲。在正式开始之前,我想先聊聊数据湖这个领域。说实话,我入行那会儿,Hadoop 刚火起来,大家都在喊“数据湖能存一切”。但真正用起来,才发现坑有多深。

今天这一章,我们就来扒一扒数据湖的痛点,看看 Delta Lake 是怎么解决这些问题的。嗯,这部分内容偏概念,但很重要——你只有理解了“为什么”,后面学“怎么做”才会顺手。

1.1 数据湖的“美丽”与“残酷”

数据湖的概念,最早是 2010 年左右提出的。它的初衷很简单:把所有原始数据,不管结构化还是非结构化,一股脑儿丢进去。你想想看,这多方便?不用提前设计表结构,不用纠结数据格式,存就完了。

但理想很丰满,现实很骨感。我在 2016 年参与过一个大型电商平台的数据平台重构,当时我们用的就是纯 HDFS + Hive 的架构。刚开始还好,数据量一上来,问题就全暴露了。

数据湖的三大核心痛点:

  • 数据质量无法保证——写入一半任务失败,数据就坏了。你永远不知道读到的数据是不是完整的。
  • 缺乏事务支持——多个任务同时写同一个表,互相覆盖,数据乱成一锅粥。
  • 元数据管理混乱——HDFS 上成千上万个 Parquet 文件,哪个是新的?哪个是旧的?全靠猜。

说白了,传统数据湖就是个“数据沼泽”。数据进去容易,想拿出来用,难。

1.2 一个真实的“数据沼泽”案例

我记得有一次,业务方要跑一份前一天的销售报表。我们凌晨跑了个批处理任务,结果写到一半,集群资源不够,任务挂了。第二天一看,表里只有一半的数据。更惨的是,另一个团队同时也在写同一个表,他们的数据把我们的覆盖了。

你猜怎么着?我们花了整整两天去排查数据不一致的问题。最后发现,HDFS 上同一个分区目录下,有 3 个不同版本的文件,时间戳还互相交叉。这种问题,在传统数据湖里几乎无解。

避坑指南:我曾经见过一个团队,为了修复数据不一致,手动写脚本去 HDFS 上删文件、改时间戳。结果越修越乱,最后只能从备份恢复。记住:没有 ACID 事务的数据湖,就是定时炸弹。

1.3 ACID 事务:数据湖的“救星”

那么,怎么解决这些问题?答案就是 ACID 事务。

ACID 是数据库领域的四个特性:原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation)、持久性(Durability)。传统数据库早就有了,但数据湖领域一直没人做。直到 Delta Lake 出现。

Delta Lake 把 ACID 事务带到了数据湖里。它的核心思路很简单:用事务日志(Transaction Log)来记录每一次数据变更。你每次写入、更新、删除,都会在日志里留下记录。读数据的时候,Delta Lake 只读取最新的、已提交的版本。

特性 传统数据湖 Delta Lake
原子性 写入一半失败,数据损坏 写入失败自动回滚,数据完整
一致性 多个任务互相覆盖 事务隔离,互不干扰
隔离性 读数据可能读到中间状态 只读已提交的数据
持久性 依赖 HDFS 自身机制 事务日志保证数据不丢

你可能会问:这跟数据库的 ACID 有什么区别?其实原理差不多,但实现难度大得多。因为数据湖底层是分布式文件系统,不是数据库引擎。Delta Lake 能在 HDFS 或对象存储上实现 ACID,这本身就是个技术突破。

1.4 Delta Lake 核心特性概览

除了 ACID 事务,Delta Lake 还有几个杀手级特性。我个人觉得,这些特性才是它真正能打的地方。

  • Schema 演进与强制——你可以在不中断服务的情况下,给表加字段、改类型。同时,写入数据时自动校验 Schema,防止脏数据混进来。
  • 时间旅行(Time Travel)——可以查询任意历史版本的数据。比如你想看昨天的数据长什么样,直接指定版本号就行。
  • 数据版本管理——每次写入都会生成一个新版本。你可以回滚到任意版本,也可以清理旧版本释放空间。
  • 统一批流处理——同一个表,既支持批处理,也支持流处理。不用再维护两套数据了。
  • 高效的数据压缩与清理——自动合并小文件,清理过期数据,性能比原生 Parquet 好很多。

个人经验:我在做实时数仓项目时,最头疼的就是批流数据不一致。批处理写一份,流处理写一份,最后对不上账。用了 Delta Lake 之后,批流共用同一张表,数据天然一致。这个体验,谁用谁知道。

1.5 Delta Lake 架构总览

下面这张图,是我自己画的 Delta Lake 核心架构。你可以看到,它本质上是在 Parquet 文件之上,加了一层事务日志(Transaction Log)。所有读写操作,都要先过事务日志这一关。

Delta Lake 核心架构图 Delta Lake 核心架构 Spark / Flink / Presto 等计算引擎 Delta Lake 核心层 ACID 事务 · Schema 管理 · 版本控制 · 时间旅行 事务日志 (Transaction Log) _delta_log/ 目录下 JSON 文件 数据文件 Parquet 格式 分布式存储层 (HDFS / S3 / ADLS / GCS) 核心思想:所有读写操作先经过事务日志,保证 ACID 特性,再操作实际数据文件

从架构图可以看出,Delta Lake 并没有替换底层的存储系统。它只是在 Parquet 文件外面包了一层“事务管理层”。这意味着,你现有的 HDFS 或 S3 存储可以继续用,不需要迁移数据。

1.6 为什么选择 Delta Lake?

市面上类似的方案还有 Apache Iceberg 和 Apache Hudi。我三个都用过,简单说说我的感受。

特性 Delta Lake Apache Iceberg Apache Hudi
ACID 事务 ✅ 原生支持 ✅ 原生支持 ✅ 原生支持
Schema 演进 ✅ 自动演进 ✅ 自动演进 ⚠️ 部分支持
时间旅行 ✅ 版本号 + 时间戳 ✅ 快照 ID ✅ 时间戳
批流统一 ✅ 原生支持 ⚠️ 需额外配置 ✅ 原生支持
Spark 集成 ✅ 最紧密 ✅ 良好 ✅ 良好
社区活跃度 ⭐ Databricks 主导 ⭐ 开源社区 ⭐ Uber 开源

我个人习惯用 Delta Lake,主要是因为它跟 Spark 的集成最紧密。你想想看,如果你的技术栈里已经有 Spark,那 Delta Lake 几乎是零成本接入。而且 Databricks 一直在持续投入,生态越来越完善。

一句话总结:Delta Lake 不是要取代数据湖,而是给数据湖装上“事务引擎”。它解决了数据湖最核心的痛点——数据质量不可控、并发写入冲突、元数据管理混乱。