1. 为什么总有人在这两个词上栽跟头:先厘清“模式”而不是“存储”
前阵子帮一家创业公司做技术评审,他们的数据团队leader信誓旦旦地讲:“我们已经把数仓全部迁到了数据湖上,现在数据湖就是我们的数仓。”我问他数据怎么组织的,他说“Parquet文件一股脑扔S3里,要用的时候临时拉”。再问数据质量怎么保障,他说“业务部门自己看着办”。这种场景我见过太多次了——很多人把数据仓库和数据湖当成单纯的存储选型,其实这是两种完全不同的数据管理哲学。
先说一个最容易混的点:数据仓库是“写时建模”,数据湖是“读时建模”。这句话是理解两者差异的总钥匙。
传统数仓的理念是:数据进来之前,先想清楚它长什么样、代表什么、怎么关联。就像图书管理员在买书之前就规划好了书架编号、分类规则、索引卡片,每本新书进馆按既定规则摆放,读者查询时才能秒级定位。整个过程叫ETL(抽取-转换-加载),数据在写入阶段就已经被清洗、标准化、建模,使用的时候拿到的是规规整整的“成品”。
数据湖的理念反过来了:先把所有数据原样扔进一个巨大的池子,不管它是结构化表格、半结构化的JSON日志,还是非结构化的图片视频音频,先存下来再说。存的时候不急着定义它的用途、格式、关联关系,等将来某个业务方说“我要分析这批东西”时,再现场设计读取逻辑,这个过程叫ELT(抽取-加载-转换)。就像你家里有一个大收纳箱,所有东西先扔进去,哪天要用了再翻出来整理。
对比一个典型场景就明白了:业务系统每天产生一批订单明细文件,字段有变更有新增。在数仓里,你必须先改表结构、调整ETL映射、重跑历史数据,才能查询新字段;在数据湖里,文件直接丢进去,查询时用SQL引擎现场解析新字段,旧查询不受影响。
这个本质差异带来了一连串连锁反应:存储成本、查询性能、数据治理难度、使用灵活性,全部不同。我在后续章节详细拆开讲。
2. 从一份订单数据的完整旅程,看两类系统的设计取舍
光讲概念太空了。我拿一个真实业务来推演:假设你是电商平台,每天产生千万级订单数据,现在需要做“按用户维度的消费行为分析”。同一个需求,在数仓和数据湖里的处理路径完全不同。
2.1 在数据仓库里的处理路径
订单数据从业务库出来,先经过清洗:去掉测试订单、填充缺失值、统一金额单位;再转换:把商品ID关联到商品维表,把订单时间对齐到日期维表,把用户ID关联到用户画像;最后加载到一个叫fact_order的星型模型事实表中。整个过程是固定管道,跑批任务定时调度,结果写入高性能存储(比如ClickHouse、Doris或者传统MPP数据库)。
分析师查询“近30天高价值用户的下单频次”时,SQL直接扫事实表,因为数据已经按用户维度做了预聚合,毫秒到秒级出结果。这个过程非常稳定,但代价是:改模型很痛苦。如果业务方说我不要按用户维度了,要按商品品类分析,那就要重建一整套维度和事实表,重跑历史数据。数仓的排期通常以天为单位,从需求提出到数据可查,往往要一周以上。
2.2 在数据湖里的处理路径
订单数据直接以Parquet格式写进数据湖的raw/order/目录,分区按照dt=2024-01-01这样的结构组织。不建表、不建模、不校验格式。分析师想查高价值用户的消费行为,直接写一条Spark SQL或者Trino查询,在读取时现场做关联、过滤、聚合。
这个过程灵活到什么程度?你不需要提前定义“高价值用户”的口径——在SQL里现场用窗口函数算就行。今天觉得消费金额前10%算高价值,明天改成交互频次第20百分位以上算高价值,随时改随时查。业务口径还没定的时候,数据湖能让你边探索边定口径,这是数仓给不了的。
但代价也很明显:每次查询都要全量扫描/过滤底层文件,计算引擎要现场解析整个目录结构,如果文件数量太多或者格式不优,一个查询跑十几分钟甚至更久很正常。而且由于没有统一的模型层,同一个指标在不同人写的查询里口径可能完全不同——A算的GMV含退款订单,B算的GMV不含,两个人各自认为自己对。
2.3 两者对比,直接拉一张表
| 对比维度 | 数据仓库 | 数据湖 |
|---|---|---|
| 建模时机 | 写入前(schema-on-write) | 读取时(schema-on-read) |
| 数据形态 | 已清洗、已建模的结构化数据 | 原始数据为主,格式多样 |
| 查询延迟 | 低(毫秒~秒级) | 高(秒~分钟级) |
| 存储成本 | 高(需要高性能存储) | 低(廉价对象存储) |
| 灵活性 | 低,改模型成本高 | 高,随时尝试任意分析 |
| 数据质量 | 强,有统一标准 | 弱,依赖使用方自行把控 |
| 使用人群 | 分析师、报表系统 | 数据科学家、临时探索人员 |
| 对应存储引擎 | MPP数据库、OLAP引擎 | Hadoop、Spark、Iceberg等 |
从这个表格能看出来,数仓和数据湖不是升级关系,而是面向不同场景的差异化工具。用数仓的核心诉求是稳定可靠地支撑报表和固定看板;用数据湖的核心诉求是灵活低成本地支撑探索和分析。
3. 选型判断框架:你的业务到底处在哪个阶段
最蠢的决策方式是“因为数据湖很火所以我要上数据湖”,或者反过来“数据仓库是老技术我们不用了”。我自己的经验是,从三个维度来逼自己做判断。
3.1 业务对数据延迟的容忍度
如果是实时风控、实时大屏、OLTP联机分析这种——查询必须秒出、延迟抖一下就报警——那没得商量,必须用数仓或者至少用支持索引预聚合的OLAP引擎。数据湖的现场解析模式在延迟上先天吃亏,你可以在湖上做优化,但天花板就摆在那里。
如果是离线报表、T+1分析、机器学习训练样本准备——查询跑几分钟能接受——那数据湖完全够用,甚至更合适,因为训练样本通常需要大量探索性清洗,数据湖的灵活性正好匹配。
3.2 数据形态的多样性
我见过最典型的“数仓之痛”:一家物流公司想把快递柜的摄像头录像、传感器日志和运单数据放在一起分析。运单数据放数仓没问题,但录像文件和日志进了数仓基本就是灾难——要么转格式存Blob,失去分析能力,要么塞进数仓的二进制字段,查询时完全用不上。这种情况下数据湖是唯一合理选择。
反过来,如果你的数据基本都是业务库的表,用数仓从成本、效率、治理上都是最优的。判断标准很简单:你日常处理的数据里,结构化表格占多少?如果低于80%,建议认真考虑数据湖。
3.3 团队的建模能力和治理习惯
这部分是最容易被低估的。数据湖的灵活性是把双刃剑:它把数据治理的责任从“平台侧”转移到了“使用方侧”。没有建模能力、没有元数据管理工具、没有数据质量监控体系的团队,上了数据湖大概率会变成“数据沼泽”——所有数据扔进去找不着、不知道谁在用、口径乱成一锅粥。
之前见过一个真实案例:某零售企业上了数据湖,三个月后湖里躺了2万多张“临时表”,一半以上没人知道是谁建的、逻辑是什么。反观数仓,因为写入前就要强制建模,反而逼着团队想清楚。
我的建议:技术团队少于10人、还没有专职数据工程师的时候,老老实实用数仓,选个开源的Doris或者ClickHouse就行。等团队规模上来了,再来谈数据湖的架构优势。
4. 架构实战:数据仓库与数据湖的常见协同模式
实际生产环境里,绝大多数中大型企业不是二选一,而是“湖仓并行、数据分层”。下面是我观察到的几种高频架构模式,以及它们各自适合的场景。
4.1 数据湖为基座,数仓为输出层
这是目前最主流的数据架构演进方向。原始数据先进数据湖——成本低、不限制格式,所有明细数据、日志、归档数据都在湖里完整保留;然后通过调度任务把湖里的数据按需抽取、建模、聚合,装载到数仓的模型层,供报表和固定分析使用。
这种模式的最大优点:湖是“数据全集”,仓是“数据精品”。任何历史数据都能在湖里找到原始凭证,数仓只保留高质量、高复用度的模型数据。遇到数仓模型算错或口径大改,可以从湖里重新跑一遍,不用发愁原始数据丢了。
4.2 数仓支撑日常分析,数据湖承载临时探索
如果团队已经有成熟的数仓体系,不必强拆。我见过不少团队的做法是:日常看板、固定报表走数仓,所有“没有明确口径的探索性分析”一律引导到数据湖上去跑。数据湖上建一套完整的原始数据接入链路,分析师自己拉数据自己算,不用再排队改数仓模型。
这种模式的好处极其明显:数仓团队的工作量急降,分析师自主性大增。坏处是需要在数据湖上做一定程度的元数据登记(比如用Hive Metastore或者Glue Catalog挂表),否则湖上数据没人找得到。
4.3 利用湖格式技术实现“湖上建仓”
这几年Iceberg、Hudi、Delta Lake这类湖表格式技术发展得很快,它们把数仓的ACID事务、时间旅行、增量读取能力带到了数据湖上。听起来很完美,但我必须提醒几句。
我自己的实测经验:Iceberg在并发写入场景下性能还是没法跟成熟的MPP数仓比,而且技术栈复杂度陡增——你要维护Hive Metastore、Spark/Flink引擎、文件压缩调度、快照过期策略。团队没有专门的大数据平台组,慎上。
就拿数据回滚和时间旅行来说:Iceberg确实能让你把表回滚到任意快照,但快照文件会疯狂膨胀,没人定期清理的话,存储成本直接翻倍。我在后面第5节专门列了一堆翻车点。
4.4 选型决策表,直接抄作业
| 业务场景 | 推荐架构 | 理由 |
|---|---|---|
| 百人以上团队,有专职数据平台组 | 数据湖+数仓双层,或湖仓一体 | 能驾驭复杂度 |
| 中小团队,核心需求是固定报表 | 单数仓(Doris/ClickHouse) | 上手快,运维简单 |
| 大量非结构化数据分析需求 | 必上数据湖 | 数仓存不了/难分析 |
| 实时性要求高的场景 | 数仓+实时链路(如Flink写入Doris) | 延迟敏感 |
| 数据科学团队做模型训练 | 数据湖为主 | 灵活探索样本特征 |
5. 数据湖的隐藏成本与翻车现场
数据湖看起来是“便宜大碗”,但生产环境跑起来,隐形坑一个接一个。我挑几个最常见的展开讲,这些是我自己和客户们踩过的真实坑,不是网上抄来的。
5.1 小文件问题:数据湖性能杀手
数据湖底层通常挂对象存储(S3、OSS、HDFS),而这玩意最怕大量小文件。举个例子:Flink实时写数据湖,默认的checkpoint频率如果设置很高——比如每5秒一个checkpoint——一天下来可能产生上百万个小文件。查询时要频繁打开/关闭文件句柄,集群元数据服务直接被压垮。
解决思路:用Iceberg的RewriteDataFiles定期合并小文件,或者在Flink端增加写入buffer、降低checkpoint频率、用分区粒度控制文件大小。我建议的优化路径是:小文件合并任务每1小时跑一次,目标文件大小控制在128MB-512MB之间。这块具体参数没有通解,得用你的实际数据量和查询频次来试。
5.2 元数据失控:湖里的表没人说得清
文件存了一堆,但“这个目录是什么数据、字段含义是什么、谁负责更新”这些元信息完全没记录,是数据湖最常见的腐化路径。很多团队以为用Hive Metastore挂个表就够了,但元数据不止是schema,还包括数据血缘、数据owner、更新频率、质量规则。
我的应对经验是:建湖第一天就强制登记元数据。没有登记的数据不允许写入事实目录,宁可多花时间在前期,也比后期捞数据时大海捞针强。用Apache Atlas或者DataHub这种工具做自动血缘采集,再配一个字段注释规范,基本能解决问题。
5.3 权限模型混乱:数据泄露的温床
对象存储上的目录权限和SQL引擎里的行级/列级权限是脱节的。生产上最常见的翻车案例:数据湖里存了用户手机号、身份证、地址,但分析师用Athena/Trino查询时能SELECT整个表,没有任何行级限制。这时候你再回头看数仓——通常有完整的权限模型和脱敏策略——差距就出来了。
我的建议:数据湖上必须做统一权限网关,至少要接一层Ranger或者类似组件,给不同角色分库分表授权,敏感字段强制脱敏。对象存储的IAM权限只是第一层,不是全部。
5.4 数据质量没人负责:湖里的脏数据拖垮下游
数仓里,ETL任务失败会有告警、有重跑、有补偿机制;数据湖里,文件写了一半就标记完成的情况太常见了。最坑的是:下游任务读到脏文件不知道,导致分析结果偏差,业务方拿着错数据做了决策,回头追责发现根因在数据湖的写入链路上。
建议在数据湖写入链路里加一个质量校验步骤:文件落库后,计算引擎抽查行数、空值率、主键去重率,不达标就打回重跑,达标才算任务成功。这部分可以用Apache Griffin或者自研,但千万别省。
6. 一个真实落地节奏的数据架构演进路径参考
最后,我拿一个真实的金融行业场景来串一下前面所有内容——这里可以引用热搜里提到的中行广东分行这类实践方向,但我不讨论具体某个机构,只讲这类场景下最常见的数据架构演进路径。
6.1 起步阶段(0-1年):单数仓打天下
刚起步的团队,核心诉求是“先把报表跑起来、把业务口径定下来”。这时候不需要数据湖,一套成熟的数仓方案就够。选型建议:如果用云,直接上云数仓(如Redshift、MaxCompute);如果自建,Doris或ClickHouse能覆盖绝大多数需求。这个阶段最重要的是建立维度建模规范和数据质量体系,而不是追逐潮流。
6.2 扩张阶段(1-3年):湖仓双层并行
业务变多、数据源变杂(日志、传感数据、外部三方数据),数仓的存储成本和建模周期开始卡脖子。这个阶段就开始建设数据湖,把原始数据湖作为公共服务层,所有原始数据先沉淀到湖区;数仓保留服务质量和模型资产。双层的核心挑战是:湖到仓的数据装载链路必须可靠,调度、监控、重试机制做扎实。
6.3 成熟阶段(3年以上):湖仓一体
当团队掌握了Iceberg/Hudi这类湖表格式,数据工程师能力也到位了,再考虑把部分数仓模型迁到湖上,实现“一份存储、多种引擎”。这也是主流厂商(Databricks、华为FusionInsight等)在推的方向。但我必须泼冷水:湖仓一体的收益主要体现在节省了数据搬迁的成本和扩大数据分析的边界,同时这个阶段大幅依赖团队工程能力。我见过不少团队上了湖仓一体后,因为Flink/Spark调优不到位,性能比原来的MPP数仓差了两三倍,还得请外部专家救火。
所以就落地路径来看,很多金融、政企用户的节奏是:数仓先行把业务跑稳,再逐步引入湖的能力,等工程团队真正能驾驭大数据组件之后,才谈架构大合并。数据架构没有一步到位的银弹,只有匹配当前阶段的最优解。
6.4 决策自查清单,动手前过一遍
- 数据延迟要求:秒级还是分钟级或离线?
- 数据格式多样性:结构化数据占比高不高?
- 团队规模:有没有专职的大数据平台工程师?
- 治理需求:是否需要行级权限、脱敏、数据血缘?
- 成本预算:存储成本优先,还是研发人力优先?
这张清单每一行都值得认真思考。我自己在无数的架构评审里,见过太多因为跳过其中某条而翻车的项目——尤其是团队规模这条,很多人以为上个数据湖框架不费事,结果运维半年后哭着改回数仓。
做数据架构选择,先别急着追新,把业务需求、团队能力、数据形态、成本模型想清楚,比选哪个具体技术栈重要得多。你可以从数仓起步,也可以从湖起步,但真正关键的是搞清楚自己当前到底需要什么,以及未来一年会需要什么。这个判断做对了,后续的架构演进才走得稳。