如果你在大数据领域工作,"数据湖"这个词一定听过很多次。但它到底是什么?和数据仓库有什么区别?为什么需要它?本文用尽量简单的方式讲清楚这些问题。
从一个真实问题出发
假设你在一家电商公司,每天产生大量数据:用户的点击日志、订单记录、商品图片、客服聊天记录、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 这样的格式,让数据湖具备事务支持和查询优化能力,同时保留数据湖的低成本和灵活性。如果你在做大数据平台,数据湖是绕不开的基础设施;如果你只是做业务分析,传统数据仓库往往已经足够。