上一篇讲了 Hadoop 生态。本篇讲现代大数据栈的演进——对象存储和 Kubernetes 如何逐步替代 HDFS 和 YARN。

云原生大数据栈常被简化成"把 Hadoop 搬到云上"。这个简化漏了核心架构变化。准确的说法是:现代大数据栈把 Hadoop 的"存储 + 计算 + 编排"三层各自独立演化——存储层从 HDFS 切到 S3 / OSS 等对象存储(彻底解耦存储与计算)、计算层从 MapReduce 演进到 Spark / Flink(内存优先 + 流批一体)、编排层从 YARN 切到 Kubernetes(弹性扩缩容 + 多租户隔离)。三层解耦后每个组件独立演化、独立计费、独立运维,让大数据栈从"集成式 Hadoop 集群"变成"组合式数据平台"。

本篇只抓一个问题:对象存储为什么能取代 HDFS、Spark on K8s 现在能取代 YARN 多少、现代大数据栈与 Hadoop 的具体架构差异、什么场景应该选哪种。

存储层:HDFS vs 对象存储

HDFS 在 Hadoop 1.x 时代是大数据存储的事实标准。它的核心设计是"专用集群 + NameNode 元数据 + DataNode 块存储"——节点既存数据又跑计算,通过本地读实现高吞吐。

对象存储(S3 2006、OSS 2013、GCS 2010、Azure Blob 2009)是公有云提供的托管存储服务。用户不接触底层节点,通过 HTTP API 读写 object。

两者的核心架构差异:

1
2
3
4
5
6
7
8
9
10
11
12
                          HDFS                         对象存储(S3 / OSS)
───────────────── ────────────────────── ──────────────────────────
存储模型 文件 + 目录 + Block Object + Bucket + Key
元数据 NameNode 全内存 Object metadata 服务
API POSIX-like(hdfs 命令) HTTP REST(PUT / GET)
一致性 Strong(写入立即可见) Read-after-write strong(部分最终一致)
延迟 ~10ms(本地读) ~50ms(HTTP + 远端)
吞吐 受集群规模限制 接近无限(按 object 并行)
元数据操作延迟 ~1ms ~100ms(HTTP 握手)
持久性 3 副本 后端 11 个 9(多 AZ + EC)
运维 自建集群 + DIY 托管服务,按使用付费
成本模型 节点固定(CAPEX) 按 GB 月 + 请求次数(OPEX)

对象存储的几个关键优势让它逐步取代 HDFS:

第一,运营成本。HDFS 集群的固定节点成本与数据量线性相关——10 PB 数据需要至少 30 PB 物理存储(3 副本)+ NameNode 内存 + 运维人力。对象存储按 GB 月计费(S3 Standard 约 $0.023/GB/月),不需要采购节点、不需要 NameNode 运维。对 1 PB 以下规模的数据,对象存储成本通常低于自建 HDFS。

第二,弹性。HDFS 集群扩容需要采购新节点、配置机架、平衡数据(DataNode rebalancing 耗时几天)。对象存储容量"无限",无需规划扩容。

第三,持久性。S3 标准存储承诺 11 个 9(99.999999999%)的持久性,通过多 AZ + 纠删码实现。HDFS 3 副本在多个节点同时宕机时仍然可能丢数据(虽然概率极低)。

第四,与计算解耦。HDFS 的"计算与数据同节点"假设让集群规模与数据量绑定。对象存储的"存储独立、计算拉取"模式让计算集群可以按需扩缩,不需要承担存储责任。

代价是延迟和元数据操作效率。HDFS 的本地读延迟 10ms,对象存储的 HTTP 拉取延迟 50ms+。MapReduce / Spark 的"数据本地化"优化在对象存储上失效——所有数据都要通过网络拉取,性能下降。

Hadoop 3.x 引入了对对象存储的本地支持(S3A、ABFS、GCS connector),让 Hadoop 客户端可以直接访问对象存储。但 Hadoop 工具链(Hive、HBase、Spark)从 HDFS 切到对象存储仍然需要调优——例如 Spark 用对象存储做 Shuffle 落盘时性能下降(对象存储元数据操作慢)。

计算层:YARN vs Kubernetes

YARN 是 Hadoop 2.x 引入的资源管理层。它的设计假设是"长期集群 + 固定节点 + Container 隔离"。YARN 的 Container 是 cgroups + JVM 进程,启动开销几秒到几十秒。

Kubernetes 是云原生时代的容器编排标准(Google 2014 开源,灵感来自 Borg)。K8s 的 Pod 是 Docker / containerd 容器,启动开销从毫秒(已 cache 镜像)到几十秒(首次拉镜像)。

两者的核心架构差异:

1
2
3
4
5
6
7
8
9
10
11
                          YARN                          Kubernetes
───────────────── ────────────────────── ──────────────────────────
调度单位 Container Pod
隔离 cgroups + JVM namespace + cgroups + 容器
镜像 jar 文件(HDFS) OCI Image(Docker Registry)
启动开销 几秒 毫秒到几十秒
网络 每容器独立端口 每容器独立 IP(CNI)
存储挂载 本地目录 PersistentVolume / hostPath
弹性扩缩 不擅长(固定节点) Autoscaler 原生支持
多租户 通过队列 ACL 通过 namespace + RBAC
生态 Hadoop 工具链 云原生全栈

K8s 相对 YARN 的几个关键优势:

第一,弹性。K8s 集群可以按需扩缩节点(Cluster Autoscaler),作业提交时按需拉起 Pod,作业完成后释放。YARN 集群通常是固定的,扩容需要采购节点。云上 K8s(EKS / AKS / GKE)可以与云的弹性计算(EC2 / VM)联动,让大数据作业真正按需付费。

第二,多语言。YARN 默认是 JVM 生态(Container 启动 JVM 跑 task),非 JVM 任务(Python 训练脚本、C++ 计算库)需要包装层。K8s 的容器天然支持任何语言、任何运行时——Spark / Flink / TensorFlow / PyTorch / 自定义训练任务都可以跑。

第三,生态。K8s 有海量 Operator(数据库 Operator、消息队列 Operator、AI 训练 Operator),让大数据栈与云原生生态无缝集成。YARN 的生态局限于 Hadoop 项目内。

第四,可观测性。K8s 的 Prometheus + Grafana + Fluentd + Jaeger 是事实标准。YARN 的监控是 Hadoop 特有的(Metrics V2 + History Server),不如 K8s 标准化。

代价是延迟和稳定性。YARN Container 启动比 K8s Pod 快(JVM 已 cache,几秒;K8s 第一次拉镜像可能几十秒)。短作业(几秒到几分钟)在 YARN 上启动开销小于 K8s。

K8s 上的 Spark(Spark on K8s,Spark 2.3+)已经在很多场景替代 Spark on YARN。但 K8s 上的 Flink 仍然不如 YARN 成熟(Flink 的 State Backend 与 K8s PersistentVolume 集成有挑战)。MapReduce 几乎不在 K8s 上跑(没必要——MapReduce 是 Hadoop 老技术,新作业用 Spark / Flink)。

现代大数据栈的典型架构

云原生大数据栈的典型部署:

1
2
3
4
5
6
7
8
9
10
11
1. 存储:S3 / OSS / GCS(核心数据湖)+ HDFS(兼容性,可选)
2. 表格:Iceberg / Hudi / Delta Lake(在对象存储之上提供 ACID + Schema Evolution)
3. 计算:
- 批处理:Spark on K8s
- 流处理:Flink on K8s
- 交互式 SQL:Trino / Athena / Snowflake
- 实时 OLAP:ClickHouse / Druid / Pinot
4. 编排:K8s(计算) + Argo Workflows / Airflow(作业)
5. 元数据:AWS Glue / DataHub / Amundsen
6. 监控:Prometheus + Grafana
7. CI/CD:GitOps(ArgoCD / Flux)

这个 stack 与 Hadoop 时代的对比:

Hadoop 时代:"HDFS + YARN + Hive + MapReduce"是一个集成产品,所有组件来自 Apache Hadoop 生态。

云原生时代:每个层独立选择最佳组件,组合成数据平台。存储用对象存储,表格用 Iceberg / Hudi,计算用 Spark / Flink,SQL 用 Trino,编排用 K8s,监控用 Prometheus。

这种"组合式"架构让用户不被绑死在单一供应商,可以根据需求替换组件。但代价是集成复杂度上升——需要懂多个组件,而不是只懂 Hadoop。

数据湖格式:Iceberg / Hudi / Delta Lake

对象存储之上构建数据湖有一个核心问题——对象存储本身没有 ACID 事务、Schema Evolution、Time Travel 这些数据库特性。直接在 S3 上做"insert into / update / delete"很难(需要重写整个 object)。

数据湖格式(Netflix Iceberg 2018、Uber Hudi 2017、Databricks Delta Lake 2019)填补了这个空白。它们在对象存储之上构建"表格层",提供:

ACID 事务:多个写入者并发修改同一表,保证一致性。

Schema Evolution:添加 / 删除 / 重命名列不需要重写历史数据。

Time Travel:查询历史版本的表数据(例如查询昨天的状态)。

Upsert / Delete:支持 UPDATE 和 DELETE 操作(HDFS 时代不支持)。

这三种格式的设计略有差异(Iceberg 偏查询性能、Hudi 偏流式 upsert、Delta Lake 偏 Databricks 集成),但核心目标一致——让对象存储变成"可更新的数据库"。

数据湖格式直接挑战 Hive 的地位。Hive 的表格抽象(目录 + 文件)已经过时——现代 stack 用 Iceberg / Hudi 替代 Hive,但仍然用 Hive Metastore 做 schema 共享(Hive 留下的最大遗产)。

哪些场景仍然选 Hadoop

虽然云原生 stack 在很多场景取代 Hadoop,但 Hadoop 仍然在某些场景有优势:

第一,受监管行业的数据不能离开本地数据中心。银行、电信、政府的核心数据合规要求不允许部署到公有云。这种场景必须自建集群,Hadoop 仍然是自建大数据栈的最佳选择(成熟、稳定、文档齐全)。

第二,超大规模数据 + 高频本地计算。如果一个公司每天处理 PB 级数据,从对象存储拉数据的网络成本(云上 egress 费用)可能超过自建 HDFS 的成本。这种场景 HDFS 的"数据本地化"仍然有经济优势。

第三,已有 Hadoop 团队和工具链。如果公司已经投入大量人力维护 Hadoop 集群、有完善的 Hive / HBase 应用,迁移到云原生栈的迁移成本可能超过短期收益。这种场景应该渐进演化(例如在 Hadoop 之上加 Spark,逐步用对象存储替代部分 HDFS),而不是一刀切迁移。

第四,对延迟敏感的本地访问。HBase / HDFS 的本地读延迟(毫秒级)显著优于对象存储(HTTP 几十毫秒)。对延迟极敏感的场景(实时风控、广告投放)仍然需要本地存储。

其他场景(新项目、云上部署、小规模数据)应该优先考虑云原生 stack——成本更低、运维更简单、技术栈更现代化。

实验:观察两种 stack 的对比

如果你的环境同时有 Hadoop 集群和 K8s 集群,提交同一个 Spark 作业到两个 stack:

1
2
3
4
5
6
7
8
9
10
11
# Spark on YARN
spark-submit --master yarn --deploy-mode cluster \
--class org.apache.spark.examples.SparkPi \
spark-examples_2.12-3.5.0.jar 1000

# Spark on K8s
spark-submit --master k8s://https://k8s-api:6443 \
--deploy-mode cluster \
--conf spark.kubernetes.container.image=spark:3.5.0 \
--class org.apache.spark.examples.SparkPi \
local:///opt/spark/examples/jars/spark-examples_2.12-3.5.0.jar 1000

观察两个作业的启动开销、执行时间、资源使用。K8s 上的 Spark 通常启动比 YARN 慢(镜像拉取),但运行时性能差异不大(都跑在 JVM 里)。

对象存储与 HDFS 的性能对比:

1
2
3
4
5
6
7
8
9
# 写入 100GB 数据到 HDFS
hadoop fs -put /local/100gb /hdfs/

# 写入 100GB 数据到 S3
aws s3 cp /local/100gb s3://bucket/

# 时间对比
# HDFS:约 5-10 分钟(取决于集群带宽)
# S3:约 10-30 分钟(HTTP 协议开销 + 远端网络)

对象存储写入通常比 HDFS 慢 2-3 倍(HTTP + 远端),但读取可以通过多并发 object 拉取达到与 HDFS 相当的吞吐。

模式提炼

现代大数据栈的演进体现的设计模式:

1
2
3
4
5
6
7
模式:分层解耦 + 托管服务 + 弹性扩缩 + 组合式架构

- 存储与计算解耦,各自独立演化
- 优先用托管服务(对象存储 / 托管 K8s / 托管 Spark)
- 弹性扩缩容(按需付费,不预留资源)
- 数据湖格式提供表格语义(ACID / Schema Evolution)
- 多组件组合(每个层选最佳组件,不绑死单一供应商)

这个模式与 Hadoop 时代的"集成式集群"形成对比。Hadoop 假设"所有组件来自 Apache Hadoop 项目",云原生 stack 假设"每个组件来自不同供应商,通过标准 API 集成"。

云原生大数据栈是 Hadoop 设计思想的进一步演化——Hadoop 提出的"分而治之 + 副本容错"在云原生时代仍然成立,只是实现方式从"自建集群"变成"组合托管服务"。

工程迁移表

Hadoop 概念 AWS 对应 Azure 对应 GCP 对应 开源对应
HDFS S3 ADLS Gen2 GCS MinIO / Ceph
YARN EMR / EKS AKS GKE / Dataproc Kubernetes
MapReduce EMR MapReduce HDInsight MapReduce Dataproc Spark / Flink
Hive Athena Synapse BigQuery Trino / Spark SQL
HBase DynamoDB Cosmos DB Bigtable Cassandra
Oozie Step Functions Logic Apps Workflows Argo Workflows
Flume Kinesis Event Hubs Pub/Sub Kafka + Kafka Connect
Hue QuickSight Power BI Looker Superset

注意三大云厂商都提供了"Hadoop 兼容"的托管服务(EMR、HDInsight、Dataproc),让用户可以在云上跑 Hadoop 作业。但这些服务底层已经从 HDFS 切到对象存储(EMR 默认用 S3,HDInsight 用 ADLS),从 YARN 切到 K8s(部分场景)。"Hadoop 兼容"是接口层兼容,底层架构已经是云原生。

常见误解

误解一:“对象存储完全取代了 HDFS”。对象存储在云上确实占主导,但自建数据中心里 HDFS 仍然广泛使用——监管行业、超大规模数据、对延迟敏感的场景。对象存储不是 HDFS 的完全替代品,是另一种部署选择。

误解二:“K8s 完全取代了 YARN”。K8s 在新部署里占主导,但 YARN 在已有 Hadoop 集群里仍然大量使用。Spark on K8s 的功能集在 Spark 3.x 才接近 Spark on YARN,Flink on K8s 仍然不如 Flink on YARN 成熟。

误解三:“迁移到云原生 stack 总是更便宜”。云原生 stack 减少了运维人力成本,但增加了云服务费用。对超大规模数据(PB+),云上 egress 费用 + 存储费用可能超过自建 Hadoop 成本。要做 TCO 测算,不能盲目假设云更便宜。

误解四:“数据湖格式(Iceberg / Hudi)取代了 Hive Metastore”。数据湖格式取代了 Hive 的表格抽象,但仍然用 Hive Metastore 做 schema 共享。Hive Metastore 是开源大数据生态的事实标准,被 Spark / Trino / Flink / Iceberg / Hudi 共同使用。

误解五:“Hadoop 已经死了,所有项目都应该迁移”。Hadoop 在受监管行业、超大规模数据、对延迟敏感的场景仍然有市场。盲目迁移可能成本超过收益。新项目优先云原生 stack,存量 Hadoop 按需渐进演化。

练习

  1. 在云上(AWS / Azure / GCP)创建一个 EMR / HDInsight / Dataproc 集群,观察底层存储是不是 HDFS(通常已经是对象存储)。提交一个 Hive 查询,对比与本地 Hadoop 集群的性能差异。

  2. 在 K8s 集群上提交一个 Spark 作业(Spark on K8s),观察 Driver Pod 和 Executor Pod 的启动过程。对比与 Spark on YARN 的启动开销差异。

  3. 阅读一篇数据湖格式的设计文档(Iceberg Spec 或 Delta Lake Protocol),理解它们在对象存储之上如何实现 ACID。

  4. 思考题:如果一个公司有 5 PB 历史数据存在自建 Hadoop 集群,想迁移到云原生 stack,应该按什么顺序迁移?哪些数据应该先迁移、哪些后迁移、迁移过程中如何保证业务连续性?

系列导航

序号 主题 状态
00-06 HDFS 存储层 第一阶段(已完成)
07-12 YARN 资源管理层 第二阶段(已完成)
13-15 MapReduce 计算模型 第三阶段(已完成)
16-19 HA、安全与 Common 基础设施 第四阶段(已完成)
20 Hadoop 生态:Hive、HBase、Pig 的角色分工 上一篇
21 Hadoop vs 对象存储 + Kubernetes:现代大数据栈的演进 本篇
22 Hadoop 留下的设计遗产:从 GFS / MapReduce 到云原生 下一篇(系列完结)

参考资料