1. Delta Lake 前世今生:数据湖的演进、Delta Lake 的诞生背景、核心特性概览
大家好,我是你们的老朋友。今天咱们正式开讲《Delta Lake 实时流批一体 Flink 方案实战》的第一章。
在正式开始之前,我想先聊聊一个很现实的问题:为什么我们需要 Delta Lake? 我最早接触大数据那会儿,Hadoop HDFS 就是神一样的存在。大家一股脑把数据往里扔,觉得「存下来就行」。但后来发现,事情没那么简单。
1.1 数据湖的演进:从「沼泽」到「湖」
数据湖这个概念,最早是 2010 年左右由 Hadoop 生态带火的。说白了,就是把所有原始数据,以原始格式存到一个统一的地方。结构化的、半结构化的、非结构化的,统统往里塞。
但理想很丰满,现实很骨感。我见过太多团队,数据湖最后变成了「数据沼泽」——数据是存进去了,但谁也读不懂、用不了。为什么?
- 缺乏事务支持:多个任务同时写同一个目录,数据就乱套了。你读到的可能是半成品。
- 没有 Schema 约束:今天写进去的字段是 A、B、C,明天变成了 A、B、D,下游消费直接报错。
- 文件碎片化:小文件成千上万,NameNode 压力大,查询性能也差。
- 数据质量无法保证:写了一半的任务挂了,留下一堆脏数据,没人知道。
嗯,这里要注意,这些问题不是 Hadoop 本身的问题,而是缺少一层「元数据管理」。传统数据仓库有 ACID 事务、有 Schema 约束,但数据湖没有。所以大家开始思考:能不能把数据仓库的「可靠性」和数据湖的「灵活性」结合起来?
于是,Lakehouse(湖仓一体) 的概念诞生了。而 Delta Lake,就是 Lakehouse 架构中最具代表性的实现之一。
核心观点:数据湖的演进,本质上是「从存得住」到「用得稳」的转变。Delta Lake 解决了数据湖缺乏事务、Schema 强制、数据质量保障的三大痛点。
1.2 Delta Lake 的诞生背景
Delta Lake 是 Databricks 公司在 2019 年开源的。我记得当时 Spark Summit 上,他们演示了一个场景:同时有 10 个流作业往同一个表里写数据,还能保证读的作业看到一致性的快照。台下掌声一片。
为什么会这样?因为 Delta Lake 在 Parquet 文件之上,加了一层事务日志(Transaction Log)。每次写操作,都会先记录日志,再提交数据。读的时候,只读已提交的版本。
说白了,Delta Lake 就是一个自带 ACID 事务的存储层。它不改变你底层的存储(还是 HDFS、S3、OSS),但让你对数据的操作变得像操作数据库一样可靠。
我个人习惯把 Delta Lake 比作「Git 版本控制 + 数据库事务」的结合体。你想想看,Git 能让你回退到任意历史版本,Delta Lake 也能做到(Time Travel)。Git 有 commit 日志,Delta Lake 也有 transaction log。
小提示:Delta Lake 的 Transaction Log 存储在 _delta_log 目录下,每个 JSON 文件就是一个 commit。你可以直接打开看看,里面记录了每次操作修改了哪些文件、增加了哪些数据。
1.3 核心特性概览
接下来,我把 Delta Lake 的核心特性梳理一下。这些特性,也是我们后续课程中反复用到的基础。
| 特性 | 说明 | 我的经验 |
|---|---|---|
| ACID 事务 | 支持可序列化隔离级别,读写互不阻塞 | 我曾经在金融项目中,用 Delta Lake 替代了 Hive + 手动锁的方案,数据一致性再也没出过问题 |
| Schema 强制与演进 | 写入时自动校验 Schema,支持自动增加列 | 注意:自动演进虽然方便,但建议生产环境手动控制,避免字段类型意外变更 |
| Time Travel | 按版本号或时间戳查询历史数据快照 | 做数据回溯审计时,这个功能简直是救命稻草 |
| 数据版本管理 | 每次操作生成一个新版本,支持回滚 | 我习惯保留最近 30 天的版本,太老的版本通过 VACUUM 清理 |
| 统一批流 | 批处理和流处理共用同一张表,语义一致 | 这是 Delta Lake 与 Flink 结合的最大价值点,后面我们会重点展开 |
| 数据文件优化 | 自动合并小文件(OPTIMIZE)、Z-Order 排序 | 我建议每天跑一次 OPTIMIZE,查询性能能提升 3-5 倍 |
| 数据质量约束 | 支持 CHECK 约束,写入时自动校验 | 比如年龄字段不能为负数,这种约束直接在表级别定义,比应用层靠谱 |
避坑指南:我曾经在生产环境中遇到过一个问题——Delta Lake 表的 _delta_log 目录下积累了上万个 JSON 文件,导致元数据操作变得非常慢。后来发现,需要定期执行 VACUUM 清理过期日志,同时开启 delta.logRetentionDuration 配置。这个坑,大家一定要记住。
1.4 Delta Lake 架构全景图
为了让大家更直观地理解 Delta Lake 的架构,我画了一张图。这张图展示了 Delta Lake 在存储层和计算层之间的位置,以及核心组件的关系。
从这张图你可以看到,Delta Lake 并不是一个独立的存储系统,而是架设在现有存储之上的「元数据管理层」。它通过 Transaction Log 来记录每一次数据变更,从而实现了 ACID 事务、版本控制、Schema 管理等能力。
1.5 为什么选择 Delta Lake + Flink?
你可能会问:市面上有 Hudi、Iceberg,为什么我们要学 Delta Lake?
我的回答是:Delta Lake 在「流批一体」这个场景上,与 Flink 的配合是最自然的。Flink 的 Checkpoint 机制和 Delta Lake 的事务日志,本质上都是「先记日志、再提交数据」的套路。两者结合,可以实现端到端的 Exactly-Once 语义。
另外,Delta Lake 的 Change Data Feed(CDF) 特性,可以直接输出增量数据变更流,Flink 消费起来非常方便。这个特性,我们在后面的章节会专门讲。
一句话总结:Delta Lake 让数据湖变得「可靠」,Flink 让数据处理变得「实时」。两者结合,就是实时湖仓一体方案的黄金搭档。