数据湖入门:它到底是做什么的

如果你在大数据领域工作,"数据湖"这个词一定听过很多次。但它到底是什么?和数据仓库有什么区别?为什么需要它?本文用尽量简单的方式讲清楚这些问题。

从一个真实问题出发

假设你在一家电商公司,每天产生大量数据:用户的点击日志、订单记录、商品图片、客服聊天记录、App 崩溃日志……这些数据格式各不相同,有结构化的(订单表)、半结构化的(JSON 日志)、非结构化的(图片、文本)。

传统做法是把这些数据分别存到不同地方:结构化数据进数据仓库(Hive/Redshift),图片进对象存储(S3/OSS),日志进 HDFS。但这带来了问题:

  • 数据散落各处,很难统一管理
  • 数据仓库要求提前定义好 Schema(表结构),新业务来了要改表,很麻烦
  • 原始数据在导入数据仓库时就被清洗和转换了,原始数据丢失,出了问题无法回溯
  • 数据仓库存储成本高,不适合存海量的低价值数据(比如每次页面滚动的日志)

数据湖就是为了解决这些问题而生的。

数据湖是什么

数据湖的核心思想是:先存,后用。把所有数据,不管什么格式、什么结构,都原样存下来,等到真正需要分析的时候再决定怎么处理。

类比一下:

  • 数据仓库像一个精装修的仓库,东西进来之前必须先分类、贴标签、放到指定位置,管理严格,但灵活性差,而且进门之前要做很多准备工作。
  • 数据湖像一个大容量的原料仓库,什么东西都往里扔,原始状态保存,需要的时候再去找、再去加工。灵活,但如果没有好的管理,就会变成一个乱糟糟的"数据沼泽"。

技术上,数据湖通常建立在廉价的分布式存储之上(HDFS 或云上的 S3/OSS),存储成本比数据仓库低一个数量级,因此可以存储海量的原始数据,包括那些"现在不知道有没有用,但先存着"的数据。

数据湖解决什么问题

Schema on Read:用的时候再定义结构

数据仓库是 Schema on Write:数据写入之前必须先定义好表结构(字段名、类型),不符合结构的数据无法写入。

数据湖是 Schema on Read:数据以原始格式存储(JSON、CSV、Parquet、图片……),读取时再解释它的结构。这意味着:

  • 新业务上线,不需要提前建表,直接把数据存进来
  • 同一份原始数据,不同团队可以用不同的 Schema 解读(业务团队和算法团队对同一份日志的需求不同)
  • 历史数据可以在未来用新的方式重新分析

保留原始数据,支持回溯

数据仓库里的数据经过了 ETL(抽取、转换、加载),原始数据已经丢失。如果发现 ETL 逻辑有 bug,历史数据无法修复。

数据湖保留原始数据,ETL 是在原始数据之上叠加的加工层。发现问题可以从原始数据重新跑,不会丢失历史。

统一存储多种数据类型

数据湖可以存结构化、半结构化、非结构化的所有数据,一个地方管全部,避免数据孤岛。机器学习需要的训练数据(图片、文本、日志)和 BI 报表需要的结构化数据可以放在同一个数据湖里。

数据湖与数据仓库的区别

  • 数据格式:数据仓库只存结构化数据;数据湖存任意格式
  • Schema 时机:数据仓库写入时定义(Schema on Write);数据湖读取时定义(Schema on Read)
  • 数据处理:数据仓库存的是加工后的数据;数据湖存的是原始数据
  • 存储成本:数据仓库存储成本高;数据湖基于廉价存储,成本低
  • 查询性能:数据仓库查询性能好(数据已经优化过);数据湖查询性能相对差(需要扫描原始文件)
  • 适用场景:数据仓库适合固定的 BI 报表和 SQL 分析;数据湖适合探索性分析、机器学习、原始数据存档

两者不是替代关系,现代架构通常是数据湖 + 数据仓库结合使用:数据湖存原始数据,数据仓库存加工后的分析数据,数据从湖流向仓。

湖仓一体:数据湖的进化

早期数据湖有一个大问题:HDFS 上的文件不支持 ACID 事务,不能做行级的 UPDATE/DELETE,也没有版本管理,数据质量难以保证。

为了解决这个问题,出现了湖仓一体(Lakehouse)格式,代表产品有三个:

Delta Lake(Databricks 开源):在 HDFS/S3 上的 Parquet 文件之上加了一层事务日志(Transaction Log),记录每次写入操作,从而支持 ACID 事务、UPDATE/DELETE、时间旅行(查询历史版本的数据)。Delta Lake 是目前最成熟的湖仓一体格式,Databricks 生态的首选。

Apache Iceberg(Netflix 开源):同样在文件存储之上加元数据层,但设计更偏向"表格式"标准,对多引擎(Spark、Flink、Trino、Hive)的支持更好。Iceberg 的隐藏分区(Hidden Partitioning)特性让分区对用户透明,避免了 Hive 分区管理的复杂性。

Apache Hudi(Uber 开源):最早专注于解决流式数据的 Upsert 问题——数据库的变更日志(CDC)实时同步到数据湖,支持高频的行级更新。Hudi 在需要近实时数据同步的场景(如数据库到数据湖的实时同步)中有优势。

这三者的共同点是:让数据湖具备了数据仓库的能力(事务、更新、查询优化),同时保留数据湖的灵活性(廉价存储、多格式、多引擎)。

-- Delta Lake 示例:支持 ACID 的 UPDATE(普通 HDFS 文件做不到)
UPDATE delta.`/data/orders`
SET status = 'cancelled'
WHERE order_id = '12345';

-- 时间旅行:查询昨天的数据版本
SELECT * FROM delta.`/data/orders`
TIMESTAMP AS OF '2026-04-24 00:00:00';

-- Iceberg 示例:隐藏分区,用户不需要知道数据按日期分区
-- 查询时 Iceberg 自动做分区裁剪
SELECT * FROM orders WHERE order_date = '2026-04-25';
-- 等价于(Iceberg 自动识别):只扫描 2026-04-25 分区的文件

什么时候该用数据湖

适合数据湖的场景:

  • 数据类型多样,有日志、图片、文本、结构化数据混合存储的需求
  • 需要保留原始数据,支持未来的重新分析和数据回溯
  • 机器学习场景,需要大量原始训练数据
  • 数据量极大(PB 级),存储成本是主要考量
  • 业务变化快,Schema 经常变动,不想频繁改表

不适合数据湖的场景:

  • 需要低延迟的在线查询(数据湖的查询延迟通常在秒到分钟级)
  • 需要复杂的多表 JOIN 和聚合报表,且对查询性能要求很高(数据仓库更合适)
  • 数据量不大(TB 级以下),数据仓库的管理成本更低、查询更快

总结

数据湖的本质是廉价存储 + 原始数据 + 灵活分析。它不是数据仓库的替代品,而是数据仓库的补充——数据仓库管理加工后的高质量数据,数据湖存储原始的全量数据。

现代数据架构的演进方向是湖仓一体:用 Delta Lake/Iceberg/Hudi 这样的格式,让数据湖具备事务支持和查询优化能力,同时保留数据湖的低成本和灵活性。如果你在做大数据平台,数据湖是绕不开的基础设施;如果你只是做业务分析,传统数据仓库往往已经足够。