部署Spark Standalone 高可用集群
部署Spark Standalone 高可用集群
适用版本:Spark 4.0+(要求 JDK 17+,内置 Scala 2.13)、ZooKeeper 集群已部署完成(安装步骤省略,复用三节点 ZooKeeper 集群)。
集群规模:Spark Master × 2、Spark Worker × 3,通过 ZooKeeper 实现 Master 主备选举与状态恢复。
1. 集群规划
| 节点 | 角色 | 说明 |
|---|---|---|
| node01 | Zookeeper + Master + Worker | Master 主/备由 ZooKeeper 选举产生,不固定 |
| node02 | Zookeeper + Master + Worker | 同上 |
| node03 | Zookeeper + Worker | 纯计算节点 |
ZooKeeper 集群连接串(已部署):node01:2181,node02:2181,node03:2181
涉及端口:
| 端口 | 用途 |
|---|---|
| 7077 | Master RPC 端口(应用、Worker 连接) |
| 8080 | Master Web UI |
| 8081 | Worker Web UI |
2. 前置条件
2.1 安装 JDK 17(Spark 4.0 起不再支持 Java 8/11,三台节点均执行)
tar zxf jdk-17.0.11_linux-x64_bin.tar.gz -C /opt/
cat >> /etc/profile << 'EOF'
export JAVA_HOME=/opt/jdk-17.0.11
export PATH=$JAVA_HOME/bin:$PATH
EOF
source /etc/profile
java -version # 应显示 17.x
2.2 主机名解析与免密登录
确认三台节点 /etc/hosts 已配置 node01/node02/node03 互相解析,且节点间 SSH 免密已配置(一键脚本依赖)。
2.3 确认 ZooKeeper 集群健康
zkServer.sh status # 三台中应显示 1 个 leader、2 个 follower
3. 安装 Spark(三台节点均执行)
# 下载(以 4.0.0 为例,可替换为 4.x 更新版本)
wget https://archive.apache.org/dist/spark/spark-4.0.0/spark-4.0.0-bin-hadoop3.tgz
# 解压并创建软连接
tar zxf spark-4.0.0-bin-hadoop3.tgz -C /opt/
cd /opt
ln -s spark-4.0.0-bin-hadoop3 /opt/spark
4. 配置 spark-env.sh(HA 核心配置)
cd /opt/spark/conf
cp spark-env.sh.template spark-env.sh
vim spark-env.sh
添加如下内容:
export JAVA_HOME=/opt/jdk-17.0.11
export SPARK_HOME=/opt/spark
# 注意:HA 模式下务必注释掉或不要设置 SPARK_MASTER_HOST,
# 否则两个 Master 都会认为自己是 Leader,无法构成主备
# export SPARK_MASTER_HOST=node01
export SPARK_MASTER_PORT=7077
export SPARK_MASTER_WEBUI_PORT=8080
export SPARK_WORKER_DIR=/data/spark/work
# 日志目录(可选,默认在 $SPARK_HOME/logs)
export SPARK_LOG_DIR=/data/spark/logs
# ZooKeeper HA 配置(两个 Master 节点配置必须完全一致)
export SPARK_DAEMON_JAVA_OPTS="-Dspark.deploy.recoveryMode=ZOOKEEPER \
-Dspark.deploy.zookeeper.url=node01:2181,node02:2181,node03:2181 \
-Dspark.deploy.zookeeper.dir=/spark"
参数说明:
| 参数 | 含义 |
|---|---|
spark.deploy.recoveryMode | 恢复模式,设为 ZOOKEEPER 启用主备选举 |
spark.deploy.zookeeper.url | ZooKeeper 集群连接串(主机名:端口,逗号分隔) |
spark.deploy.zookeeper.dir | Spark 在 ZooKeeper 中存储集群状态(Worker、Driver、Application)的目录,默认 /spark |
5. 配置 workers 文件
cp workers.template workers
vim /opt/spark/conf/workers
内容如下(即 3 个 Worker 节点):
node01
node02
node03
6. 配置 spark-defaults.conf(可选,推荐)
cp spark-defaults.conf.template spark-defaults.conf
vim /opt/spark/conf/spark-defaults.conf
添加如下内容:
# 应用默认连接的 Master 列表(两个 Master 都写上,逗号分隔)
spark.master spark://node01:7077,node02:7077
# 每个 Worker 节点可分配给 Executor 的最大内存
spark.worker.memory 16g
# 每个 Worker 节点可分配的 CPU 核数
spark.worker.cores 8
# 本地存储优化
spark.local.dir /opt/spark/local
# 应用完成后自动清理本地目录
spark.worker.cleanup.enabled true
# 清理周期(秒)
spark.worker.cleanup.interval 600
# 保留时间1天(秒)
spark.worker.cleanup.appDataTtl 3600
若不在此配置,提交应用时需显式指定:
spark-submit --master spark://node01:7077,node02:7077 ...
7. 分发配置并配置环境变量
# 在 node01 上执行,将配置分发到另外两个节点(Spark 安装目录整体拷贝一次即可)
scp -r /opt/spark-4.0.0-bin-hadoop3 node02:/opt/
scp -r /opt/spark-4.0.0-bin-hadoop3 node03:/opt/
# node02、node03 上同样创建软连接
ln -s /opt/spark-4.0.0-bin-hadoop3 /opt/spark
# 三台节点均配置环境变量
cat >> /etc/profile << 'EOF'
export SPARK_HOME=/opt/spark
export PATH=$SPARK_HOME/bin:$SPARK_HOME/sbin:$PATH
EOF
source /etc/profile
# 创建日志、工作、临时目录
mkdir -p /data/spark/{logs,work,local}
8. 启动集群
启动顺序:先启动两个 Master(完成 ZooKeeper 选举),再启动 Worker。ZooKeeper 集群需已处于运行状态。
# node01 执行:启动 Master1 + 所有 Worker
start-all.sh
# node02 执行:启动 Master2(Standby)
start-master.sh
如果希望 Worker 启动时就同时感知两个 Master(推荐,故障切换更平滑),可改用以下方式启动 Worker:
# 三个 Worker 节点分别执行(或用一键脚本统一执行)
start-worker.sh spark://node01:7077,node02:7077
9. 验证高可用
9.1 查看进程
# node01、node02 上应有 Master 和 Worker 进程
jps | grep -E 'Master|Worker'
# node03 上应有 Worker 进程
jps | grep Worker
9.2 查看 Web UI 确认主备状态
访问 http://node01:8080 和 http://node02:8080,其中一个显示 Status: ALIVE(Active Master),另一个显示 Status: STANDBY。两个页面都能看到 3 个 Alive Worker。
如果两个 Master 都显示 ALIVE,说明 ZooKeeper HA 配置没有生效(通常是
SPARK_DAEMON_JAVA_OPTS拼写错误、或配置了SPARK_MASTER_HOST),此时两个 Master 各自独立调度,集群处于不健康状态,必须修复后重启。
9.3 故障切换测试
# 在 Active Master 所在节点杀掉 Master 进程
stop-master.sh # 或 kill -9 <Master PID>
观察:
- 原 Standby Master 的 Web UI 状态变为 ALIVE,日志出现
I have been elected leader!; - 等待约 1~2 分钟(新 Master 从 ZooKeeper 恢复 Worker/Application 状态),原 Standby 页面上 3 个 Worker 恢复 Alive;
- 期间正在运行的应用不受影响,仅新应用提交会被短暂阻塞。
恢复后,可将原 Master 重新启动作为新的 Standby:
start-master.sh
9.4 提交测试应用
spark-submit --master spark://node01:7077,node02:7077 \
--class org.apache.spark.examples.SparkPi \
/opt/spark/examples/jars/spark-examples_2.13-4.0.0.jar 100
10. 集群一键启停脚本
在 node01 创建 spark-cluster.sh:
vim /opt/spark/sbin/spark-cluster.sh
内容如下:
#!/bin/bash
SPARK_HOME=/opt/spark
MASTERS=(node01 node02)
WORKERS=(node01 node02 node03)
MASTER_URL="spark://node01:7077,node02:7077"
case "$1" in
start)
for m in "${MASTERS[@]}"; do
echo "===== Starting Master on $m ====="
ssh $m "$SPARK_HOME/sbin/start-master.sh"
done
echo "===== Waiting for master election (10s) ====="
sleep 10
for w in "${WORKERS[@]}"; do
echo "===== Starting Worker on $w ====="
ssh $w "$SPARK_HOME/sbin/start-worker.sh $MASTER_URL"
done
;;
stop)
for w in "${WORKERS[@]}"; do
echo "===== Stopping Worker on $w ====="
ssh $w "$SPARK_HOME/sbin/stop-worker.sh"
done
for m in "${MASTERS[@]}"; do
echo "===== Stopping Master on $m ====="
ssh $m "$SPARK_HOME/sbin/stop-master.sh"
done
;;
status)
for m in "${MASTERS[@]}" "${WORKERS[@]}"; do
echo "===== $m ====="
ssh $m "jps | grep -E 'Master|Worker' || echo 'no spark process'"
done
;;
*)
echo "Usage: $0 {start|stop|status}"
exit 1
esac
赋权并使用:
chmod +x /opt/spark/sbin/spark-cluster.sh
ln -s /opt/spark/sbin/spark-cluster.sh /usr/local/bin/spark-cluster
spark-cluster start # 一键启动(先 Master 后 Worker)
spark-cluster status # 查看各节点进程
spark-cluster stop # 一键停止(先 Worker 后 Master)
11. 常见问题
- 两个 Master 都是 ALIVE:
SPARK_DAEMON_JAVA_OPTS未生效或配置了两个不同的 ZooKeeper 地址。检查三台节点spark-env.sh是否一致、参数拼写是否正确,修复后重启全部 Master。 - Worker 一直处于失联状态:检查防火墙是否放行 7077/8080/8081 端口,以及 Worker 启动命令中的 Master 地址是否正确。
- 切换后 Worker 长时间不恢复:正常,新 Leader 需要 1~2 分钟从 ZooKeeper 恢复状态并等待 Worker 重新注册;期间可查看新 Master 日志
$SPARK_LOG_DIR/spark-*-Master-*.out中的Recovery complete字样确认恢复完成。 - 应用提交报错 Master 不可连接:确认应用使用的 master URL 同时包含两个 Master(
spark://node01:7077,node02:7077),否则 Active Master 故障时应用无法自动切换。
部署Spark Standalone 高可用集群
https://www.zyifei.top/archives/e0c0b6a6-6ca4-43e0-a0c9-6a5a611aee78
评论