很多 Spark 使用者对两件事一直模糊:
一是
client / cluster到底差在哪;二是 STS(Spark Thrift Server)算不算一种提交模式。
这篇文章只讲一件事:一次提交,Driver 是怎么被启动的,STS 又在这个模型里扮演什么角色。
一、Spark 提交模式,本质上只回答一个问题
Spark 里真正干活的有两类 JVM:
- Driver :大脑(SQL 解析、Stage 拆分、Task 调度)(这里是最多二开和改造的地方)
- Executor:劳工(读数据、计算、写数据)
所谓提交模式,不决定"用不用 Spark",只决定:
Driver JVM 在哪台机器上出生。
Driver 是一个进程
二、client 模式:spark-submit 自己就是 Driver
1️⃣ 从敲命令开始
bash
spark-submit \
--master yarn \
--deploy-mode client \
com.xxx.MySparkApp
这条命令做了什么?
- 启动一个 JVM,进程名是
SparkSubmit - 在这个 JVM 里,通过反射调用你的
MySparkApp.main() main()里new SparkSession()→new SparkContext()
👉 到这一步,Driver 已经存在了,而且就是 spark-submit 这个进程。
没有任何远程启动 Driver 的动作。
2️⃣ Driver 向 YARN 要资源
SparkContext 初始化时:
- 向 ResourceManager 申请第一个 Container
- 这个 Container 里跑的是 ApplicationMaster(AM)
在 client 模式下,AM 只干一件事: 帮 Driver 申请 Executor。
3️⃣ Executor 反向连 Driver
Executor 启动后,通过 Driver 的 RPC 地址连回来:
Executor ──RPC──▶ Driver(spark-submit 所在机器)
Driver 负责:(Driver就像大脑,而且当计算任务比较多时,任务就会比较重)
- 切 Stage
- 下发 Task
- 收集结果
AM 全程不参与计算。
client 模式一句话总结
Driver 在提交机上,提交机不关机,App 就活着。
三、cluster 模式:Driver 被塞进 YARN 里
1️⃣ 提交机只做"投递"
bash
spark-submit \
--master yarn \
--deploy-mode cluster \
com.xxx.MySparkApp
这次:
- spark-submit 进程只把 jar + 配置上传到 HDFS
- 向 RM 说"起个 App"
- 然后自己可以立刻退出
2️⃣ 第一个 Container 里:AM = Driver
YARN 分配第一个 Container,启动的是:
org.apache.spark.deploy.yarn.YarnClusterApplication
在这个 JVM 里:
- 创建 SparkContext
- 同时扮演 ApplicationMaster
- 自己调度自己
也就是说:
Driver 的父进程是 YARN,不是 spark-submit。
3️⃣ Executor 仍然只认 Driver
Executor 启动后,连接的是 AM Container 里的 Driver RPC 端口。
架构变成:
spark-submit(投递员)
↓
YARN Container(Driver + AM)
↓
Executor
cluster 模式一句话总结
Driver 在集群里,提交机可以随时走人。
四、两种模式的本质差异(只看这一句)
| 模式 | Driver 在哪 | 提交机作用 |
|---|---|---|
| client | 提交机 | 启动 Driver |
| cluster | YARN Container | 只负责提交 |
其他所有差异------日志、稳定性、端口、是否适合生产------都是这个事实的副作用。
五、Spark Thrift Server 是什么?
1️⃣ STS 不是新东西
启动 STS:
bash
start-thriftserver.sh
等价于:
bash
spark-submit \
org.apache.spark.sql.hive.thriftserver.HiveThriftServer2
👉 STS 本身就是一个 Spark Application。
2️⃣ 它为什么能接受 SQL?
HiveThriftServer2 的 main() 做了三件事:
- 创建
SparkSession - 启动一个 Thrift RPC 服务(默认 10000 端口)
- 永远不退出
BI 工具通过 JDBC 连的是:
jdbc:hive2://sts-host:10000
这个端口后面,就是 Driver 自己。 Driver被绑定到了这个Thrift RPC 服务中
3️⃣ 每一条 SQL 是什么?
BI 发 SQL → Driver 收到 → 编译成 SparkPlan → 切 Stage → 调度 Task
没有新的 Application,没有新的 spark-submit。
只是 Driver 里多了一个 Job。
4️⃣ STS 用的是哪种提交模式?
生产里几乎都是:
bash
start-thriftserver.sh --master yarn --deploy-mode client
也就是:
- Driver 在 STS 机器上
- 对外暴露 JDBC
- Executor 在 YARN / K8s 上
所以 STS 不是第三种提交模式,而是:
一个长期运行的 client-mode Spark Application,对外伪装成数据库。
六、为什么这个架构容易出问题(Driver的职责太重了)
因为 client 模式的所有特征,被"常驻"放大了:
- Driver 单点:一个 JVM 服务所有查询
- 结果集先回 Driver,再给 JDBC 客户端
- 一个慢 SQL 占满 Driver 内存 → 所有查询一起卡
- 权限、资源、隔离都只能在这个 Driver 内解决
STS 的"像数据库",其实是错觉 。
它更像:
一个永远不退出的 spark-submit,坐在那里等 SQL。
七、一句话串起来
- client:Driver 在提交机,跑完就死
- cluster:Driver 在集群,提交机可以走
- STS:Driver 在提交机,但永远不 exit,专门接 JDBC
八、如果你只记住一张图
JDBC / spark-submit
|
| RPC
v
Driver
|
调度指令
|
Executor
- client / STS:Driver 在图左边
- cluster:Driver 在图中间
补充视角(面试/架构用):
Spark 只有两种提交模式。
STS 是"client 模式的常驻服务化",Kyuubi 则是把 STS 拆成"无状态网关 + 按需 client-mode Engine"。
理解到这一步,你再看 STS 为什么被换掉,就不是"新工具更好",而是"架构假设变了"。