数据湖基础:从概念到现代技术栈

聊实时数据湖之前,咱们得先把数据湖本身搞清楚。我见过不少团队,一上来就追 Delta Lake、Iceberg,结果连数据湖和数据仓库的区别都说不清楚。嗯,这章我们就扎扎实实地把地基打牢。

什么是数据湖?

数据湖这个概念,最早是 2010 年左右由 Pentaho 的 CTO 提出的。说白了,就是一个能存任意格式、任意规模数据的集中式存储系统。你想想看,传统数据仓库要求你先定义好 schema 再存数据,但数据湖反着来——先把数据扔进去,后面再说怎么用。

我个人习惯把数据湖比作一个「数据沼泽」:刚开始啥都能往里倒,但如果不加管理,很快就会变成谁也进不去的烂泥潭。所以后来才有了 Lakehouse 架构,也就是带 ACID 事务和 schema 管理的数据湖。

数据湖的核心特征:

  • 存储所有类型的数据(结构化、半结构化、非结构化)
  • 保留原始数据格式,不做转换
  • 支持批量与流式写入
  • 计算与存储分离

数据湖 vs 数据仓库:别再傻傻分不清

我在项目中遇到过好几次,业务方问「我们已经有数据仓库了,为什么还要搞数据湖?」这个问题其实很典型。咱们直接看对比:

维度 数据仓库 数据湖
数据格式 结构化,预定义 schema 任意格式,schema 灵活
处理模式 Schema-on-Write(写时定义) Schema-on-Read(读时定义)
数据质量 高,经过 ETL 清洗 原始数据,质量参差不齐
用户群体 业务分析师、报表用户 数据科学家、数据工程师
典型场景 固定报表、BI 分析 机器学习、探索性分析
存储成本 高(需要预处理和索引) 低(对象存储为主)

你看,这两者不是替代关系,而是互补。我曾经帮一个金融客户做架构改造,他们的交易数据走数据仓库做合规报表,日志和点击流走数据湖做用户画像——各司其职,效果很好。

数据湖的核心特性

Schema-on-Read:读时再定义

这是数据湖最反直觉的地方。传统思维是「先有结构,再填数据」,但 Schema-on-Read 是「先存数据,读的时候再解释」。举个例子:

-- 传统数据仓库:必须先建表
CREATE TABLE user_log (
  user_id INT,
  action STRING,
  ts TIMESTAMP
);

-- 数据湖:直接存 JSON 文件,读的时候再解析
-- 文件内容:{"user_id": 1001, "action": "click", "ts": "2024-01-15T10:30:00"}
-- 查询时动态映射 schema
SELECT user_id, action FROM parquet.`/data/logs/2024/01/15/`

这样做的好处是什么?你想想看,业务变化那么快,今天加个字段明天改个类型,如果每次都要改表结构,运维成本太高了。数据湖让你先把数据存下来,等真正需要分析的时候再决定怎么解析。

避坑指南:我曾经接手过一个数据湖项目,团队把所有数据都按 JSON 格式存,结果查询性能惨不忍睹。后来我们强制要求:流式数据用 Avro,分析数据用 Parquet,日志用 JSON——不同场景选不同格式,别一刀切。

ACID 事务:数据湖的「成人礼」

早期的数据湖有个致命缺陷——不支持事务。你想想看,如果两个任务同时往同一个分区写数据,很容易出现数据不一致。我记得有一次线上事故,就是因为流式写入和批处理作业冲突,导致某张表的数据对不上,排查了整整两天。

现代数据湖(Lakehouse)引入了 ACID 事务,解决了这个问题:

  • 原子性(Atomicity): 写入要么全部成功,要么全部回滚
  • 一致性(Consistency): 事务前后数据状态一致
  • 隔离性(Isolation): 并发写入互不干扰
  • 持久性(Durability): 提交后的数据不会丢失

说白了,就是让数据湖拥有了数据库级别的事务保障。Delta Lake、Iceberg、Hudi 这三个主流方案,核心都在做这件事。

版本控制:时光机一样的数据回溯

这个特性我特别喜欢。传统数据仓库里,如果你误删了数据或者跑错了 ETL,恢复起来非常麻烦。但数据湖的版本控制让你可以像 Git 一样回溯到任意历史版本。

-- Delta Lake 示例:查看历史版本
DESCRIBE HISTORY events;

-- 回滚到指定版本
RESTORE TABLE events TO VERSION AS OF 42;

-- 时间旅行查询
SELECT * FROM events TIMESTAMP AS OF '2024-01-10 08:00:00'

嗯,这里要注意:版本控制不是无限保留的,需要设置合理的保留策略。我建议生产环境保留 7-30 天的历史版本,具体看你的存储成本和合规要求。

现代数据湖技术栈:三足鼎立

目前市面上主流的三个开源方案,我都有实际使用经验。咱们一个个说:

特性 Delta Lake Apache Iceberg Apache Hudi
出身 Databricks(开源) Netflix(捐赠 Apache) Uber(捐赠 Apache)
核心存储 Parquet + 事务日志 Parquet + Manifest 文件 Parquet + Timeline
事务模型 乐观并发控制 乐观并发控制 基于时间线的 MVCC
Spark 集成 原生支持 良好 良好
Flink 集成 通过 Delta Sink 原生支持 原生支持
适用场景 Databricks 生态、批流一体 多引擎兼容、云原生 增量处理、CDC 入湖

我个人习惯这样选型:

  • 如果团队主要用 Databricks,无脑选 Delta Lake
  • 如果追求多引擎兼容(Spark、Flink、Trino 混用),Iceberg 更合适
  • 如果 CDC 入湖是核心场景,Hudi 的增量处理能力最强

注意:别被「哪个更好」这种问题困扰。我见过用 Delta Lake 做 CDC 做得很好的团队,也见过用 Hudi 做分析的案例。关键看你的技术栈和团队熟悉度,没有银弹。

数据湖技术栈全景图

下面这张图展示了现代数据湖的核心组件和它们之间的关系:

现代数据湖技术栈全景 对象存储 / HDFS Parquet / Avro / ORC 事务日志 / Manifest Delta Lake Apache Iceberg Apache Hudi Apache Spark Apache Flink Trino / Presto Hive / MR 表格式层(Delta / Iceberg / Hudi)在文件格式之上提供 ACID 事务、版本控制和 schema 演化能力

从这张图可以看得很清楚:底层是对象存储或 HDFS,中间是文件格式和表格式层,上层是各种计算引擎。表格式层(Delta、Iceberg、Hudi)才是现代数据湖的灵魂——它们把普通文件变成了带事务和版本控制的「表」。

好了,数据湖的基础概念就聊到这里。记住一句话:数据湖不是一种技术,而是一种架构思想。后面的章节我们会深入每个技术细节,包括怎么用 CDC 把数据实时入湖,怎么保证一致性,怎么优化查询性能——这些才是真正落地时遇到的硬骨头。