从 Hadoop 到湖仓一体:数据平台的十年演进
从 Hadoop 到湖仓一体:数据平台的十年演进
每隔两三年,技术圈就会喊一次”Hadoop 已死”。第一次听到这话时我还是个虔诚的 Hadoop 信徒,会在 NameNode 面板前盯 Hortonworks 那一栏绿点;最近一次听到,是某个云厂商的销售在白板上把 HDFS 划掉,换成”对象存储 + Iceberg”。十多年过去了,Hadoop 真的死了吗?
我的答案是:死的从来不是 Hadoop,而是”把 Hadoop 当成一个不可分割的整体”这种思维方式。 它被解构了。HDFS 的存储能力演化为对象存储,Hive 的元数据治理演化为表格式,MapReduce/Tez 的计算模型演化为 Spark/Flink/Trino,YARN 的资源管理被 Kubernetes 和云原生调度接管。每一个组件都还在,只是各自独立演化、自由组合。
这是 Hadoop 系列的收尾篇。前面几篇我讲的是 Hadoop 内部怎么做、怎么调、怎么扛住生产流量;这一篇我想跳出来,站在数据平台演进的宏观视角,复盘这套体系如何从”一个大盒子”被拆解为”一栈可组合的湖仓”。如果你是大数据/AI 从业者,我希望这篇文章能帮你看清选型背后的脉络;如果你是招聘方,它至少能说明我对这件事的判断不只是会用几个组件。
一、Hadoop 时代的价值与局限
先把功劳说清楚。在 Hadoop 出现之前,处理 TB/PB 级数据只有两条路:昂贵的商用 MPP(Teradata、Greenplum),或者自己写 MPI。Hadoop 用”廉价存储 + 分布式计算”把大数据的门槛打到了地面,让任何一家公司都能买几台普通服务器搭起集群。这是革命性的。
它的核心架构可以用下面这张图概括:
1 | +---------------------------------------------------+ |
这套架构有几个划时代的价值:
- 存算一体化:数据散落在 DataNode 的本地磁盘上,计算任务被 YARN 调度到数据所在节点,靠”数据本地性”(data locality)避免网络 IO,把延迟压到最低。
- 统一的元数据:Hive Metastore 给全公司一张表,所有引擎对着同一份数据写 SQL,结束了”一个部门一个 ETL 孤岛”。
- 生态爆炸:Spark、Flink、Presto 都长在 HDFS + YARN 之上,构成了第一代真正的”数据平台”。
但用着用着,问题也暴露得很彻底:
1. 存储与计算耦合,扩容时一起烧钱。 HDFS 的 DataNode 既存数据又跑计算。数据量在涨,但 CPU 不一定同比例涨——你只是想多放点冷数据,却被迫采购一整套带 CPU、内存、网卡的服务器。反过来,你想扛一波临时的大查询峰值,也没法只扩计算,因为扩进来的节点上没数据。
2. 运维负担极重。 NameNode 是单点(虽然有 HA),元数据全在内存里,集群到一定规模(我经历过的上限大概在 6~7 亿文件级别 )就开始吃力:RPC 风暴、GC 停顿、滚动升级要逐台 DataNode 操作。更别提三副本带来的存储成本放大。
3. 小文件与元数据瓶颈。 Hive 默认按分区、按任务产出大量小文件,NameNode 内存吃紧,MapReduce 启动开销陡增。治小文件这件事,几乎是每个 Hadoop 团队的必修课。
4. 批处理延迟高。 MapReduce 模型天生为批而设计,端到端小时级延迟很正常。后续虽然有 Spark 把它压到分钟级,但仍然不是真正的流式。
5. 多引擎适配成本。 Spark、Flink、Presto 虽然共享 HDFS,但每个引擎有自己的优化器、自己的元数据方言、自己的分区策略。数据团队很大一部分精力,花在”让这份数据被不同引擎都能正确读”上。
这些问题不是 Hadoop 设计得不好,而是它的核心假设——“集群就是一台大计算机,存算绑定在一起最优”——在云时代失效了。云让存储和计算可以分别按量计费、弹性伸缩。Hadoop 的耦合反而成了负担。
二、解耦三件套:存储、表格式、计算
真正发生的不是”替换 Hadoop”,而是把它拆成三层,每层独立演化、独立选型。这是过去十年数据平台最关键的架构变化。
1 | +--------------------------------------------------------------------+ |
2.1 存储层:从 HDFS 到对象存储
对象存储(S3、阿里云 OSS、腾讯云 COS、Google Cloud Storage)是数据平台走向云原生的第一块基石。它和 HDFS 的根本区别在于:它把”存储服务”从”服务器”里彻底抽象出来了。
- 按量计费、近无限容量:你不再需要预估集群规模,存多少付多少。冷数据直接下沉到低频访问层(如 S3 IA、OSS 冷归档),成本可以压到标准层的三分之一甚至更低 。
- 完全免运维:没有 NameNode、没有 DataNode、没有磁盘故障、没有副本手工修复。对象存储的 11 个 9 持久性由云厂商兜底。
- 天然解耦:存储和计算不再绑定在同一个物理集群,你可以挂 10 个引擎对着同一桶数据读,互不干扰。
但天下没有免费的午餐。对象存储的代价是:
- 延迟更高:一次 list 操作比 HDFS 的元数据 RPC 慢一个数量级,对小文件密集的查询很不友好。
- 早期的一致性问题:经典 S3 是”读后写一致”但”列表后创建一致”有延迟,曾经需要 S3Guard 这类客户端补丁来模拟强一致。后来 S3、OSS、COS 都陆续提供了强一致性,问题才算根治,但旧的工程经验里仍要警惕。
2.2 表格式:给对象存储装上”数据库的灵魂”
对象存储本身只是”一个桶装一堆文件”。没有 ACID、没有 schema、没有分区自动演进、没有 time travel。这就意味着:两个流同时往一个表写、读的时候写到一半,或者想回滚到昨天的数据状态,全都做不到。
表格式(Table Format)就是来填这个坑的。 它在对象存储之上加了一层”元数据 + 协议”,把一堆松散的文件变成一张可以事务性读写的表。今天主流的三个开源方案是 Iceberg、Hudi、Delta Lake,它们都在 2017~2019 年间成熟起来,正好踩在对象存储普及的节点上。
一个表格式大致负责这些事:
- ACID 事务:原子提交,读写隔离,并发写入不会读到半成品。
- Time Travel:每个快照是一个可读版本,可以查”昨天的这张表长什么样”。
- Schema Evolution & Partition Evolution:加列、改分区策略不用重写全表。
- 统计信息 / Data Skipping:每个数据文件记录 min/max,查询时按谓词跳过无关文件,这是性能的关键。
三者的设计取向不同,下表是一个我实际选型时会看的对比:
| 维度 | Iceberg | Hudi | Delta Lake |
|---|---|---|---|
| 起源 | Netflix,2018 捐 Apache | Uber,2016 捐 Apache | Databricks,2019 开源 |
| 核心定位 | 开放表格式,引擎中立 | 流式入湖 + 增数更新 | 与 Spark/Photon 深度绑定 |
| 写模型 | Copy-on-Write / Merge-on-Read | Copy-on-Write / Merge-on-Read | Copy-on-Write / Merge-on-Read |
| 引擎生态 | Spark/Flink/Trino/StarRocks/… 全面 | Spark/Flink/Trino 为主 | Spark 生态最成熟 |
| 元数据管理 | 自管理元数据树,无外部依赖 | 依赖 Hive Metastore 或自定义 | 依赖 Hive Metastore(开源版) |
| schema/分区演进 | 最强,分区演化是亮点 | 较强 | 一般 |
| 适用场景 | 多引擎、统一表格式底座 | 高频 upsert、CDC 入湖 | Databricks 平台内首选 |
我在实际项目里倾向用 Iceberg 做”统一底座”,因为它引擎中立、分区演进最成熟;Hudi 在高频 CDC 入湖的场景仍然很有竞争力;Delta 的优势在 Databricks 平台内才能完全发挥,纯开源版用起来要绕一些坑 。
2.3 计算层:一个底座,多个引擎
解耦带来的最大红利,是计算引擎可以按负载选型,而不再被迫”一招鲜”。
- Spark:大规模批处理和 ETL 的主力,2026 年仍然是离线数仓的事实标准。
- Flink:流式计算的王者,配合 Iceberg/Hudi 的流式写入,实现真正的”流批一体”。
- Trino(原 PrestoSQL):交互式 ad-hoc 查询,秒级响应,BI 场景首选。
- StarRocks / Doris:MPP 架构的 OLAP 引擎,面向对延迟敏感的实时看板。
这些引擎共享同一份对象存储 + 表格式底座,各取所长。这是我十年前在 Hadoop 上想都不敢想的事——那时候换一个引擎,等于重做一整套数据。
三、湖仓一体:在”湖”上加一层”仓”
把上面三层拼起来,就得到了”湖仓一体”(Lakehouse)这个词。这个概念由 Databricks 在 2020 年提出,但它本质上描述的是一个早就该有的架构形态。
数据湖(Data Lake) 是对象存储 + 一堆文件,灵活但不可靠——schema 后置、数据质量差、被称为”数据沼泽”。
数据仓库(Data Warehouse) 结构严谨、ACID 完备、查询快,但封闭、贵、和湖割裂。
湖仓一体的关键判断是:不必在”湖”和”仓”之间二选一,而是在湖之上叠加仓的能力(事务、schema、性能),让一份数据同时具备两者的特性。 表格式就是这层”叠加”。
1 | 传统数据湖: 传统数仓: 湖仓一体: |
湖仓一体真正爆发的另一个推手是批流一体。Flink 流式写入 Iceberg,把分钟级的实时数据直接落到同一张表上,离线批处理和实时分析共享一份存储。过去”Lambda 架构”里维护两套(speed layer + batch layer)、还要做数据对齐的痛苦,被彻底简化了。
存算分离带来的弹性伸缩是另一个红利。查询峰值来了,临时拉起 50 个 Trino worker 跑 10 分钟,跑完释放,只付那 10 分钟的钱。这种弹性在 Hadoop 时代是不可想象的。
四、HDFS 的现代角色:别急着一刀切
讲到这里,很容易得出”对象存储全面替代 HDFS”的结论。但这是过度简化。HDFS 在 2026 年仍然有它不可替代的位置,关键看负载特征。
HDFS 仍然占优的场景:
- 热数据 + 数据本地性:把计算调度到数据所在节点,避免对象存储的网络往返。对延迟敏感的随机读、对吞吐要求极高的大扫描,HDFS 仍有优势。
- 低延迟随机读:HBase、Impala 这类依赖短路径本地读的引擎,在 HDFS 上能跑出对象存储难以企及的尾部延迟。
- 已有大规模集群的存量投资:PB 级数据迁移到对象存储本身是一件成本不低、风险不小的事,没有强动机不必动。
HDFS 不再占优的场景:
- 冷数据归档:用三副本存冷数据是巨大的浪费,应该下沉到对象存储,配合纠删码(erasure coding)把存储成本进一步压下来。HDFS 3.x 也原生支持了 EC,但对象存储 + EC 的组合在成本和运维上仍然更香。
- 弹性计算峰值:HDFS 集群扩容以”天/周”为单位,对象存储 + 弹性计算以”分钟”为单位。
一个常见的现代布局是分层存储: 热数据放 HDFS(或者干脆放本地 SSD 缓存),温数据放对象存储标准层,冷数据放对象存储的低频访问层。计算引擎透明地跨层访问,由表格式屏蔽底层差异。这才是务实的姿态,而不是追新把 HDFS 一刀切掉。
五、一条可落地的迁移/分层路径
下面是我实际操刀过的、相对稳妥的一条演进路径,不一定最优,但踩过的坑可以分享。
1 | 阶段 1:纯 Hadoop 阶段 2:引入冷层 阶段 3:统一表格式 |
阶段 2 的关键动作:引入对象存储做冷层。 先不碰表格式,只做”冷热分离”。把超过 N 天没被访问的 HDFS 数据归档到对象存储,HDFS 上保留热数据。这步投入小、风险低,能立刻省下可观的存储成本。注意要确认引擎对 S3A/OSS Connector 的兼容性,以及访问凭证的统一管理。
阶段 3 的关键动作:引入 Iceberg 统一表格式。 新建表直接用 Iceberg,存量 Hive 表按价值优先级分批迁移。最容易踩的坑是元数据迁移:Iceberg 的 catalog(Hive Catalog、REST Catalog、Glue Catalog)和 Hive Metastore 不是一回事,迁移过程中通常要双跑一段时间,让旧引擎读老表、新引擎读 Iceberg 表,再逐步切换。
阶段 4 的关键动作:Flink 实时入湖。 把 Kafka 上的实时数据用 Flink 流式写入 Iceberg,配合 write.parallelism 和 checkpoint 间隔控制小文件产出。这一步的关键坑是小文件和 compaction:流式写入天然产生大量小文件,必须配套一个 compaction 任务(Iceberg 的 rewrite_data_files)定期合并,否则 Trino 查询会被 list 操作拖死。我一般把 compaction 调成小时级异步任务,配合分区粒度做差异化策略。
阶段 5:作为 AI 数据底座。 这点单独在下一节展开。
几个通用的踩坑提醒:
- 查询性能:从 Hive 迁到 Iceberg,简单查询未必更快(甚至更慢),Iceberg 的优势在分区裁剪和 Data Skipping,要确保统计信息被正确收集。复杂查询、大表扫描才会真正受益。
- 双写过渡期:在切换期间,同一份逻辑数据可能同时存在于 Hive 表和 Iceberg 表,要有一套机制保证读一致性,避免双写不一致导致的口径混乱。
- 小文件治理:流式入湖几乎一定会带来小文件问题,把 compaction 当成一等公民来设计,而不是事后补救。
- 成本监控:对象存储的请求次数是要收费的,Trino 一个不当的
SELECT *可能让你的 S3 账单翻几倍。配合清单(Inventory)和访问日志做成本归因。
六、与 AI 的衔接:湖仓是特征与语料的统一底座
到 2026 年,数据平台的下一站已经不是 OLAP,而是 AI。大模型把”数据基建”这件事的重要性推到了前所未有的高度——训练需要海量语料,RAG 需要高质量的知识库,特征工程需要统一、可复用、可追溯的特征。
湖仓一体天然适合扮演这个角色:
- 特征工程的单一来源:特征被组织成 Iceberg 表,训练任务和在线推理服务共享同一份定义,避免了”训练用一份数据、线上用另一份数据”的漂移。
- RAG 的知识底座:文档、向量化结果、检索日志都可以是湖仓里的表,Trino 做离线分析,Flink 做实时更新,模型服务做在线检索。
- 可追溯(Time Travel):模型出了问题,可以回溯到训练时用的那份数据快照,而不是只能猜。
- 存算分离对 GPU 友好:训练任务临时拉起一批 GPU pod,直接挂载对象存储读取湖仓数据,跑完释放,这正是云原生 AI 的标准姿势。
换句话说,湖仓不只是数据团队的资产,它正在变成整个 AI 团队的底座。 这也是为什么我认为每一个有志于做大数据架构的人,都必须把湖仓这件事理解透彻——它已经不只是一个数据仓库的升级版,而是整个数据与智能体系的”地基”。
七、反思与展望:按负载选架构,而不是追新
写到这里,我必须强调一件事:这篇不是在劝你立刻把 HDFS 拆了换成 Iceberg。 技术选型最忌讳的就是拿着锤子找钉子。
我在过去几年见过太多”为了湖仓而湖仓”的翻车案例:几百 GB 的数据量,硬上对象存储 + Iceberg + Flink + Trino 全家桶,运维复杂度比原来的一个 MySQL 高出三个数量级,最后还是退回了数仓。也见过传统金融客户,监管要求强一致 + 低延迟,老老实实用 Hadoop 集群反而最稳。
一个相对靠谱的判断框架:
| 负载特征 | 倾向架构 |
|---|---|
| 数据量 PB 级 + 多引擎共享 + 需要弹性 | 湖仓一体(对象存储 + Iceberg + 多引擎) |
| 实时性要求高 + 流批一体 | 湖仓一体(Flink 流式写入 Iceberg) |
| 数据量中等 + 查询性能优先 + 模型相对固定 | MPP 数仓(StarRocks / Doris / Snowflake) |
| 已有大规模 Hadoop + 监管严格 + 本地性敏感 | Hadoop 分层存储,渐进引入对象存储冷层 |
| AI 训练 + 大规模语料/特征 | 湖仓一体作为数据底座,对象存储 + 弹性 GPU |
未来几年我比较关注的几个方向:一是 catalog 层的标准化(REST Catalog、Unity、Polaris 这些试图把元数据治理也云原生化);二是表格式和向量检索的融合(湖仓内直接做向量索引);三是数据网格(Data Mesh)和组织治理如何与湖仓底座结合。这些都不是要立刻上的东西,但值得保持关注。
小结
从 2010 年我第一次敲下 hadoop fs -ls 到今天,数据平台走完了从一个”大盒子”到”一栈可组合服务”的成熟之旅。Hadoop 没有死,它只是被解构了——它的存储能力演化成了对象存储,它的元数据治理演化成了表格式,它的计算模型演化成了 Spark/Flink/Trino,它的资源调度演化成了 Kubernetes。
这不是某个技术的胜利,而是整个大数据工程从”装在一起的一体机”走向”可组合的乐高”。湖仓一体是这个成熟过程的标志,但它不会是终点——下一个十年,AI 会继续重塑这套体系,而理解”为什么会有今天的架构”的人,才能在下一个十年不迷失方向。
按负载选架构,不为新而新,这是我做大数据这些年最深的一句心得。希望这篇复盘对你有用。
