在 YARN 模式下,Spark 的 Client 模式和 Cluster 模式有什么区别?
在 Spark On YARN 模式下,Client 模式和 Cluster 模式最核心的区别在于 Driver 程序运行的位置。
这一区别导致了它们在网络通信、日志查看、程序稳定性以及适用场景上的显著不同。
以下是详细的对比分析:
1. 核心区别:Driver 运行位置
- Client 模式 (YARN-Client):
- Driver 运行在提交任务的客户端机器上(即你敲
spark-submit命令的那台机器,通常称为 Edge Node 或 Gateway)。 - Cluster 中的 ApplicationMaster (AM) 仅负责向 YARN ResourceManager 申请资源,不运行 Driver 代码。
- Driver 运行在提交任务的客户端机器上(即你敲
- Cluster 模式 (YARN-Cluster):
- Driver 运行在 YARN 集群内部的某个节点上。
- 具体来说,Driver 程序运行在 ApplicationMaster (AM) 的 Container 内部。客户端提交完任务后,Driver 就与客户端脱离了关系。
2. 详细对比维度
A. 客户端依赖与生命周期 (Lifecycle)
- Client 模式:
- 客户端(终端)必须保持在线。如果你关闭了终端或按了
Ctrl+C,Driver 进程就会结束,整个 Spark 任务也会随之失败。 - 特点: 客户端与集群紧密耦合。
- 客户端(终端)必须保持在线。如果你关闭了终端或按了
- Cluster 模式:
- 客户端在提交任务后可以立即退出(Fire and Forget)。任务会在集群中独立运行,不受客户端网络断开或关机的影响。
- 特点: 异步提交,客户端与集群解耦。
B. 日志查看 (Logs)
- Client 模式:
- Driver 的日志(
System.out,System.err)会直接输出到客户端的控制台/终端。 - 优势: 非常方便即时查看程序运行状态和报错信息。
- Driver 的日志(
- Cluster 模式:
- Driver 的日志在集群节点的容器里。客户端控制台只能看到任务提交的状态(ACCEPTED, RUNNING, FINISHED),看不到具体的程序日志。
- 查看方式: 需要通过 YARN 的 Web UI 或者使用命令
yarn logs -applicationId <app_id>来查看。
C. 网络流量 (Network I/O)
- Client 模式:
- Driver 需要与集群中所有的 Executor 进行通信(调度任务、广播变量、收集结果)。
- 如果任务很大(Executor 很多),大量的网络流量会涌向客户端机器。这会导致客户端网卡成为瓶颈,甚至导致 OOM。
- Cluster 模式:
- Driver 运行在集群内部,与 Executor 之间的通信是集群内部节点的通信。
- 这种方式网络传输速度更快,且不会对提交任务的客户端机器造成压力。
D. ApplicationMaster (AM) 的职责
- Client 模式:
- AM 的作用较小,它只负责向 YARN 申请资源(Container),然后告诉 Client:“资源准备好了,你可以指挥 Executor 干活了”。
- Cluster 模式:
- AM 的作用很大,它既要向 YARN 申请资源,同时它自己就是 Driver,负责任务的调度和监控。
3. 适用场景
| 模式 | 适用场景 | 理由 |
|---|---|---|
| Client 模式 | 开发、调试、交互式查询 | 能够实时看到日志输出,方便 Debug。spark-shell 和 pyspark 必须运行在 Client 模式下。 |
| Cluster 模式 | 生产环境 (Production) | 稳定性高,不依赖客户端连接;减轻了提交机(Edge Node)的网络和内存压力,适合大规模作业。 |
4. 总结图解 (文字版)
YARN-Client 流程:
- 客户端启动 Driver。
- 客户端向 YARN 申请启动 AM。
- AM 启动,向 YARN 申请 Executor 资源。
- Driver (在客户端) 直接与 Executor (在集群) 通信并分配任务。
YARN-Cluster 流程:
- 客户端向 YARN 提交应用。
- YARN 在某个节点启动 AM。
- AM 内部启动 Driver。
- AM/Driver 向 YARN 申请 Executor 资源。
- Driver (在集群 AM 内) 与 Executor (在集群) 通信并分配任务。
- 客户端任务完成,退出。
一句话总结
如果你在写代码找 Bug,用 Client 模式;如果你代码写完了要上线跑定时任务,用 Cluster 模式。