Spark 部署模式
概述
Spark 可以运行在多种资源管理器上:自带 Standalone、企业常用的 YARN、云原生的 Kubernetes,以及本地 Local。选择部署模式直接决定资源管理、运维复杂度与成本。本文对比四种模式,讲解 Client/Cluster 部署差异与动态资源分配。
一、四种部署模式总览
| 模式 | 资源管理 | 适用场景 | 复杂度 |
|---|---|---|---|
| Local | 本机 | 开发、测试 | 最低 |
| Standalone | Spark 自带 Master/Worker | 小集群、学习 | 低 |
| YARN | 大数据集群统一资源 | 生产离线批处理 | 中 |
| Kubernetes | 容器编排 | 云原生、弹性伸缩 | 高 |
二、Local 模式
| 特点 | 说明 |
|---|---|
| 单机运行 | Driver/Executor 同进程 |
| 快速验证 | 无需集群 |
| 并行度 | local[n] 指定线程数 |
bash
spark-submit --master local[4] app.py三、Standalone 模式
3.1 架构
Master(资源调度)
├── Worker(节点)
│ └── Executor
├── Worker
│ └── Executor
└── Worker
└── Executor| 组件 | 职责 |
|---|---|
| Master | 资源调度、分配 Executor |
| Worker | 管理节点 Executor |
| Executor | 执行 Task |
3.2 特点
| 优点 | 缺点 |
|---|---|
| 简单、独立 | 无多租户隔离 |
| 无额外依赖 | 无队列管理 |
| 适合中小集群 | 与大数据生态集成弱 |
bash
./sbin/start-master.sh
./sbin/start-worker.sh spark://host:7077
spark-submit --master spark://host:7077 app.py四、YARN 模式(生产主流)
4.1 YARN 交互
spark-submit --master yarn [--deploy-mode client|cluster]
client 模式:
提交节点运行 Driver
┌──────────┐ ┌──────────────────────┐
│ Driver │◄────►│ YARN RM → NM → Container │
│(客户端) │ │ Executor │
└──────────┘ └──────────────────────┘
cluster 模式:
Driver 跑在集群内(AM 中)
┌─────────────────────────────────────┐
│ AM(ApplicationMaster) 内含 Driver │
│ └─ 申请 Container 跑 Executor │
└─────────────────────────────────────┘4.2 client vs cluster 对比
| 对比 | client | cluster |
|---|---|---|
| Driver 位置 | 提交节点 | 集群 AM |
| 日志查看 | 本地直接看 | 走 YARN 日志 |
| 适合场景 | 交互式、调试 | 生产批任务 |
| 资源占用 | 客户端占资源 | 集群内统一 |
4.3 提交示例
bash
spark-submit \
--master yarn \
--deploy-mode cluster \
--queue data \
--num-executors 20 \
--executor-memory 8g \
--executor-cores 4 \
--driver-memory 4g \
app.jar五、Kubernetes 模式
5.1 特点
| 优点 | 说明 |
|---|---|
| 弹性伸缩 | 按 Pod 扩缩容 |
| 资源隔离 | 容器级隔离 |
| 云原生 | 与云平台集成 |
| 挑战 | 说明 |
|---|---|
| 运维复杂 | 需要 K8s 知识与权限 |
| 网络 | 容器网络配置 |
| 存储 | 数据本地性难保证 |
5.2 提交示例
bash
spark-submit \
--master k8s://https://<k8s-apiserver> \
--deploy-mode cluster \
--conf spark.kubernetes.container.image=spark:3.5 \
--conf spark.kubernetes.namespace=spark \
app.py六、部署模式选型决策
场景 → 选择
┌─────────────────────────────────────────────┐
│ 学习/开发验证 → Local │
│ 小规模独立部署 → Standalone │
│ 已有 Hadoop 集群 → YARN(生产主流) │
│ 云原生、容器化 → Kubernetes │
│ 交互式 Notebook → Local/Client 模式 │
└─────────────────────────────────────────────┘6.1 混合考虑因素
| 因素 | 说明 |
|---|---|
| 已有基础设施 | 有 Hadoop 用 YARN,有 K8s 用 K8s |
| 多租户需求 | YARN/K8s 有队列与命名空间隔离 |
| 运维成本 | Standalone 最低,K8s 最高 |
| 动态扩缩 | YARN/K8s 支持动态资源分配 |
七、动态资源分配(YARN/K8s)
7.1 配置
| 参数 | 默认 | 说明 |
|---|---|---|
spark.dynamicAllocation.enabled | false | 开启动态分配 |
spark.dynamicAllocation.minExecutors | 0 | 最小 Executor |
spark.dynamicAllocation.maxExecutors | 无穷 | 最大 Executor |
spark.dynamicAllocation.initialExecutors | - | 初始数 |
spark.dynamicAllocation.executorIdleTimeout | 60s | 空闲回收时间 |
spark.dynamicAllocation.schedulerBacklogTimeout | 1s | 排队任务超时申请 |
7.2 YARN 下注意
YARN 动态分配必须开启 External Shuffle Service:
spark.shuffle.service.enabled=true
否则 Executor 回收时 Shuffle 数据丢失7.3 适用场景
| 场景 | 建议 |
|---|---|
| 共享集群、任务波动 | 开启,省资源 |
| 独占集群、SLA 稳定 | 固定资源更可控 |
八、资源参数最佳实践
8.1 Executor 规格设计
内存:8-16g 常见,避免单 Executor 内存过大导致 GC
核数:2-4 核/Executor,并发 Task 数与核数匹配
数量:总数 = 核数总量 ÷ 每 Executor 核数8.2 比例参考
经验比例:并行度 = Executor 核数总量 × 2~3
Task 数不足时,分区数决定并行度,需 repartition常见问题速查
| 问题 | 原因与处理 |
|---|---|
| yarn 队列资源不足 | 申请队列容量或减小 Executor 规格 |
| cluster 模式日志难查 | 用 yarn logs -applicationId 查看 |
| 动态分配不生效 | 检查 external shuffle service 是否开启 |
| Driver 与 Executor 版本不一致 | 统一 spark 版本与依赖 |
| K8s 权限不足 | 配置 ServiceAccount 与 RBAC 权限 |