Spark 核心之 YARN-Client 模式:原理、流程与源码级深度拆解

摘要:YARN-Client 是生产环境中使用最广泛的 Spark 部署模式。它的独特之处在于------Driver 运行在提交客户端,而 ApplicationMaster 退化为轻量级的 ExecutorLauncher,仅负责向 ResourceManager 申请 Container 启动 Executor。本文从 YARN 架构模型、AM 特殊角色、12 步启动流程、与 Standalone 对比四个维度,配合 2 张原创深色架构图 + 完整代码示例,带你彻底吃透 YARN-Client 模式的每一个细节。

关键词:Spark on YARN, YARN-Client, ResourceManager, ApplicationMaster, NodeManager, Container, ExecutorLauncher, Hadoop


一、开篇:为什么 YARN 是生产环境的首选?

前两篇文章我们分别深度拆解了 Standalone-Client 和 Standalone-Cluster 模式。但在实际生产环境中,绝大多数 Spark 集群都运行在 YARN 之上,而非 Spark 自带的 Standalone 模式。

原因很直接:

复制代码
Standalone          YARN
──────────          ────
Spark 专有            Hadoop 生态标准
无细粒度资源隔离       Container 级别的 CPU/内存隔离
不支持多租户           YARN Queue 天然多租户
独立集群管理           与 HDFS / Hive / HBase 统一调度

用一句话概括:

Standalone 是 Spark 的入门模式,YARN 是 Spark 的生产模式。

而我们今天要讲的 YARN-Client 模式,是 YARN 上最常用于交互式查询和开发调试的模式。它的核心设计思想与 Standalone-Client 如出一辙------Driver 在客户端运行,但底层资源调度完全由 YARN 负责。


二、YARN 架构基础

2.1 YARN 四大角色

理解 YARN-Client 之前,必须理解 YARN 的基础架构:

角色 职责 对应 Standalone
ResourceManager (RM) 全局资源管理与调度 ≈ Spark Master
NodeManager (NM) 单节点资源监控与 Container 管理 ≈ Spark Worker
ApplicationMaster (AM) 单个应用的生命周期管理 无直接对应 🔑
Container 抽象资源容器(CPU + 内存) ≈ Executor

2.2 YARN-Client 模式核心特征

三条核心设计原则:

  1. Driver 在客户端,AM 是轻量 ExecutorLauncher:Driver 不做任何 YARN 资源协商------这一切由 AM(ExecutorLauncher)代理完成。AM 的职责非常单一:向 RM 申请 Container、通知 NM 启动 Executor、把 Executor 信息反馈给 Driver。

  2. Driver 与 Executor 直连通信:Executor 在 NM 分配的 Container 中启动后,直接向客户端 Driver 反向注册,与 Standalone 模式一致。RM 和 NM 不参与 Task 调度。

  3. spark-submit 必须存活:这是 YARN-Client 的"阿喀琉斯之踵"。Driver 在客户端,客户端退出 = 整个应用死亡。


三、YARN-Client vs YARN-Cluster:一张表彻底搞清

对比维度 YARN-Client YARN-Cluster
Driver 位置 提交客户端 JVM AM 所在 Container 内
AM 角色 ExecutorLauncher(轻量,仅负责资源申请) Spark 完整 Driver + 资源申请
spark-submit 生命周期 必须全程存活 提交后可退出
日志查看 控制台直接可见 yarn logs -applicationId <appId>
适用场景 spark-shell / 交互式 / 开发调试 生产定时任务
网络要求 Driver ↔ Executor 互通 集群内部闭环

四、YARN-Client 启动流程:12 步深度拆解 🔥

4.1 Phase 1:Driver 初始化 + 向 RM 提交应用

Step 1-2:

bash 复制代码
spark-submit \
  --master yarn \
  --deploy-mode client \
  --executor-memory 4G \
  --num-executors 8 \
  my-app.jar

执行流程:SparkSubmit 判断 master == "yarn" && deployMode == "client" → 在当前 JVM 创建 SparkContext → 初始化 YarnSchedulerBackend → 创建 YarnClient → 向 RM 提交 YarnClientApplication → RM 返回 appId

scala 复制代码
// 源码:YarnClientImpl.java
public YarnClientApplication createApplication() {
  ApplicationSubmissionContext appContext = 
    Records.newRecord(ApplicationSubmissionContext.class);
  GetNewApplicationResponse newApp = 
    rmClient.getNewApplication();
  // ...
  return new YarnClientApplication(newApp, appContext);
}

4.2 Phase 2:RM 调度 + NM 启动 ApplicationMaster

Step 3: RM 的 Scheduler 为 AM 分配一个 Container → 向 NM 发送 StartContainer

Step 4: NM 接收指令后分配 Container 资源 → fork 新的 JVM 进程运行 ApplicationMaster

bash 复制代码
# NM 内部等价命令
java org.apache.spark.deploy.yarn.ApplicationMaster \
  --class <user-main-class> \
  --jar <user-jar> \
  1><stdout> 2><stderr>

YARN-Client 模式的关键 :这里的 AM 不是完整的 Driver,而是 ExecutorLauncher------一个只负责申请 Executor 资源的轻量级代理。

scala 复制代码
// 源码:ApplicationMaster.scala
// YARN-Client 模式下的 AM 入口
if (isClusterMode) {
  runDriver()  // YARN-Cluster: 启动完整 Driver
} else {
  runExecutorLauncher()  // YARN-Client: 仅启动资源申请代理
}

4.3 Phase 3:AM 注册 + 循环申请 Container

Step 5: AM 向 RM 发送 RegisterApplicationMaster 注册自己。

Step 6: AM 进入心跳循环,通过 allocate() 不断向 RM 请求 Container:

scala 复制代码
// AM 心跳循环(简化)
while (!finished) {
  val response = rmClient.allocate(progress)
  // 处理 RM 分配的 Container
  for (container <- response.getAllocatedContainers) {
    // 在对应 NM 上启动 Executor
    startExecutorOnNodeManager(container)
  }
  Thread.sleep(spark.yarn.scheduler.heartbeat.interval) // 默认 3s
}

RM 分批返回 Container 列表------YARN 的资源分配是渐进式的,不像 Standalone 一次性分配全部 Executor。

4.4 Phase 4-6:后续流程

Executor 在 Container 中启动 → 反向注册到客户端 Driver → Driver 发送 Task → 应用结束 → AM 发送 FinishApplicationMaster → RM 回收全部 Container。

与 Standalone 模式的关键区别:资源回收由 RM 统一管理,无需 Driver 逐一向 Master 注销。


五、YARN 三种部署模式全景对比

维度 Standalone-Client Standalone-Cluster YARN-Client YARN-Cluster
资源管理 Spark Master Spark Master YARN RM YARN RM
Driver 位置 客户端 Worker 节点 客户端 AM Container
AM 角色 ExecutorLauncher 完整 Driver
资源隔离 Container 级别 Container 级别
多租户 ✅ YARN Queue ✅ YARN Queue
生产推荐 开发调试 中小规模 交互式生产 大规模定时任务

六、生产环境最佳实践

6.1 关键配置

bash 复制代码
spark-submit \
  --master yarn \
  --deploy-mode client \
  # Executor 配置
  --executor-memory 4G \
  --executor-cores 2 \
  --num-executors 8 \
  # Driver 配置(影响本地 JVM!)
  --driver-memory 4G \
  # YARN 特有配置
  --conf spark.yarn.am.memory=1G \        # AM 内存
  --conf spark.yarn.am.cores=1 \          # AM 核心数
  --conf spark.yarn.queue=default \       # YARN Queue
  --conf spark.yarn.maxAppAttempts=2 \    # AM 重试次数
  my-app.jar

6.2 常见故障排查

故障 1:AM 启动超时

sql 复制代码
ERROR: ApplicationMaster failed to start within 600 seconds

解决:增大 AM 超时时间和内存

bash 复制代码
--conf spark.yarn.am.waitTime=1200s
--conf spark.yarn.am.memory=2G

故障 2:Executor 无法反向注册到 Driver

vbnet 复制代码
ERROR CoarseGrainedExecutorBackend: Cannot register with driver

根因:Executor 所在的 NM 节点无法访问客户端 Driver 的 IP。YARN-Client 模式要求 Driver 主机对集群内所有 NM 可达。

解决

bash 复制代码
# 显式指定 Driver Host(多网卡机器)
--conf spark.driver.host=<公网或集群内 IP>
--conf spark.driver.port=<固定端口>

故障 3:Container 内存超限被 YARN Kill

csharp 复制代码
Container killed by YARN for exceeding memory limits

解决 :YARN 的内存限制比 Spark 更严格------spark.executor.memory 必须小于 NM 可用内存,且需要留出 overhead。


七、总结

核心知识速记

要点 一句话总结
Driver 位置 YARN-Client:提交客户端;YARN-Cluster:AM Container 内
AM 角色 YARN-Client 的 AM 是轻量 ExecutorLauncher,不做 DAG 解析
资源协商 AM 通过 allocate/allocateResponse 心跳循环向 RM 申请 Container
与 Standalone 差异 YARN 提供 Container 级资源隔离 + 多租户 Queue
生产推荐 交互式用 YARN-Client,定时任务用 YARN-Cluster
运维优势 统一 Hadoop 生态管理,日志聚合、资源隔离开箱即用

金句:在 YARN-Client 模式下,Driver 是你手中的风筝,AM 是你在集群中的信使------它替你与 YARN 谈判资源,而你只需专注于业务逻辑。


作者:starzy | AI Data Engineer / 大数据技术实践者

博客:blog.starzy.cn | GitHub:starzy1990.github.io

专注 AI Agent · LangGraph · RAG · 大数据架构 · 数据工程实践

相关推荐
用户36105886261217 小时前
Spark 核心之 Standalone-Cluster 模式:原理、流程与源码级深度拆解
spark
java1234_小锋1 天前
【免费】基于Spark实时金融交易风险监控与预测系统(Java版本+可视化大屏+Kafka+SpringBoot+Vue3) 锋哥原创出品,必属精品
大数据·spark·kafka·金融交易风险监控与预测
阿里云大数据AI技术2 天前
EMR Serverless Spark 基于 MinHash-LSH 实现 PB 级文本语义去重 4 倍加速
大数据·人工智能·spark
牛奶咖啡132 天前
大数据Hadoop运维应用实践——Spark与hadoop集群的整合_独立模式下Spark集群的安装部署
大数据·spark·spark是什么?有啥用?·spark的优缺点·spark的适用与不适用场景·独立模式下的spark集群部署·启动并测试spark集群
BD_Marathon5 天前
Spark数据源
大数据·ajax·spark
BD_Marathon5 天前
Dataset
spark
java1234_小锋7 天前
【免费】基于Spark实时电商用户行为分析与预测(Java版本+可视化大屏+Kafka+SpringBoot+Vue3) 锋哥原创出品,必属精品
java·spark·kafka·实时电商用户行为分析与预测系统
abcy0712139 天前
spark核心组件
flink·spark
极光代码工作室11 天前
基于Spark的日志监控与分析平台
大数据·hadoop·python·spark·数据可视化