Spark 3.5.1 集群完整笔记
(理论+实操 · 适配3节点CentOS环境:master/slave1/slave2 + Hadoop 3.3.6 + JDK 1.8)
第一部分:集群环境与前置准备
1.1 节点规划
| 主机名 | IP地址 | Hadoop角色 | Spark角色 |
|---|---|---|---|
| master | 192.168.128.130 | NameNode、ResourceManager、DataNode、NodeManager | Master、Driver、Worker |
| slave1 | 192.168.128.131 | SecondaryNameNode、DataNode、NodeManager | Worker |
| slave2 | 192.168.128.132 | DataNode、NodeManager | Worker |
1.2 软件版本与路径
所有操作默认在 master节点 执行,安装包均存放于/root目录:
| 软件 | 版本 | 安装包路径 | 安装目标路径 |
|---|---|---|---|
| JDK | 1.8.0_461 | 已安装 | /usr/local/jdk1.8.0_461 |
| Hadoop | 3.3.6 | 已安装 | /usr/local/hadoop-3.3.6 |
| Scala | 2.13.16 | /root/scala-2.13.16.tgz | /usr/local/scala |
| Spark | 3.5.1(适配Hadoop3、Scala2.13) | /root/spark-3.5.1-bin-hadoop3-scala2.13.tgz | /usr/local/spark |
1.3 基础环境全量验证(必须全部通过)
步骤1:主机名与hosts映射验证
集群通信的基础,三台节点必须一致。
# 查看当前主机名
hostname
# 查看hosts映射
cat /etc/hosts
标准配置(缺失则执行补全):
cat >> /etc/hosts << 'EOF'
192.168.128.130 master
192.168.128.131 slave1
192.168.128.132 slave2
EOF步骤2:SSH免密登录验证
Spark启动、文件分发依赖SSH免密,master必须能无密码登录所有节点(含自身)。
# 批量测试免密
ssh master hostname
ssh slave1 hostname
ssh slave2 hostname✅ 验证标准:执行后直接返回对应主机名,无需输入密码。

步骤3:Java环境验证
Spark底层运行在JVM上,全节点版本必须一致。
java -version
echo $JAVA_HOME✅ 预期输出:
java version "1.8.0_461"
/usr/local/jdk1.8.0_461
步骤4:启动Hadoop全集群
Spark on YARN、HDFS读写都依赖Hadoop服务,必须先启动。
# 进入Hadoop sbin目录
cd $HADOOP_HOME/sbin
# 一键启动HDFS+YARN
./start-all.sh
jps步骤5:HDFS与YARN状态验证
# 1. 验证HDFS:3台DataNode在线
hdfs dfsadmin -report | grep "Live datanodes"
# 2. 验证YARN:3台NodeManager运行
yarn node -list✅ 标准结果:
- HDFS:输出
Live datanodes (3): - YARN:Total Nodes:3,全部为
RUNNING状态

步骤6:防火墙确认
systemctl status firewalld要求为 inactive (dead),未关闭则执行:
systemctl stop firewalld
systemctl disable firewalld
第二部分:Spark 部署模式详解
Spark 支持多种部署模式,核心区别在于 Cluster Manager(集群资源管理器) 不同。
2.1 Local 模式(本地模式)
核心特点
- 单台机器运行,不涉及集群,所有进程跑在同一个JVM里
- 无需启动 Master/Worker 常驻进程,开箱即用
- 并行度由指定的CPU核数决定
适用场景
- 本地开发、代码调试
- 入门学习、逻辑验证
- 小数据量功能测试
启动方式
# 使用所有CPU核(默认)
spark-shell --master local[*]
# 指定2个CPU核
spark-shell --master local[2]2.2 Standalone 模式(独立集群模式)
核心特点
- Spark 自带的原生集群管理器,不依赖Hadoop生态
- 有独立的 Master 和 Worker 常驻进程
- 架构简单,部署方便,资源调度轻量
适用场景
- 学习Spark集群原理与运行机制
- 纯Spark技术栈、不需要Hadoop生态的场景
- 小规模生产环境
核心进程
| 进程 | 角色 | 核心职责 |
|---|---|---|
| Master | 主节点 | 集群资源调度、接收客户端请求、分配任务(Standalone模式的Cluster Manager) |
| Worker | 工作节点 | 管理本节点资源、启动并管理Executor进程 |
| Driver | 驱动程序 | 解析用户代码、生成DAG、调度Task、汇总结果 |
Driver位置说明
Standalone模式下,Driver可运行在不同位置:
| 提交方式 | Driver位置 | 说明 |
|---|---|---|
| spark-shell 交互式 | Master节点 | 启动spark-shell时,Driver运行在Master所在节点 |
| spark-submit 提交 | 提交客户端 | 本地客户端提交jar包时,Driver跑在提交机器上 |
| IDE直接运行 | 本地开发机 | IDE中配置setMaster("spark://master:7077"),Driver跑在本地 |
Standalone作业运行流程
- 客户端提交应用 → Driver进程启动
- Driver向Master注册,申请Executor资源
- Master查看Worker节点资源,通知对应Worker启动Executor
- Worker启动Executor进程,Executor反向注册到Driver
- Driver构建DAG、划分Stage,将Task分发到Executor执行
- Executor执行Task,结果返回Driver
- 作业完成,释放所有资源
💡 验证方式:启动spark-shell后,访问
http://master:8080,可在监控界面看到应用信息。
2.3 YARN 模式(企业最常用,重点掌握)
核心特点
- 使用 Hadoop YARN 作为集群资源管理器
- Spark应用作为YARN的一个作业运行
- 和Hadoop、Hive共用集群资源,整体资源利用率高
⚠️ 核心注意事项
- YARN模式不需要启动Spark独立集群! 不需要启动Master和Worker常驻进程
- Spark只是YARN的“客户端”,资源全由YARN的ResourceManager和NodeManager管理
- Standalone的8080端口UI在YARN模式下访问不了,监控看YARN的8088端口
💡 常见误区:很多初学者跑YARN模式时还去启动Spark集群,其实完全不需要。
为什么企业都用YARN?
- 资源统一管理:Hadoop、Hive、Spark共用一套YARN集群,不用维护多套集群
- 调度更成熟:YARN的队列、容量调度、资源隔离机制更完善
- 运维成本低:一套集群运维,生态打通
YARN模式的两种子模式
| 对比项 | YARN Client 模式 | YARN Cluster 模式 |
|---|---|---|
| Driver位置 | 提交作业的客户端机器 | YARN集群的ApplicationMaster中 |
| 客户端断开 | 作业终止 | 作业继续运行 |
| 日志查看 | 直接在客户端看 | 从YARN日志中查看 |
| AM职责 | 只负责申请资源 | 申请资源 + 监督作业运行 |
| 适用场景 | 调试、交互式(spark-shell/pyspark) | 生产环境、后台批处理作业 |
⚠️ 重要:
spark-shell/pyspark只能用YARN Client模式,不能用Cluster模式!因为交互式需要Driver在本地和用户交互。
YARN Cluster模式作业运行流程
- 客户端提交应用程序
- ResourceManager接收请求,在某台NodeManager上启动ApplicationMaster
- ApplicationMaster内部启动Driver Program
- ApplicationMaster向ResourceManager申请Executor资源
- ResourceManager分配资源,在各NodeManager上启动Container + Executor
- Driver将Task分发到各Executor上执行,Executor向Driver注册汇报
2.4 Mesos 模式 & Kubernetes 模式(了解)
- Mesos模式:Apache Mesos作为资源管理器,国内使用较少,了解即可
- Kubernetes模式:使用K8s作为资源管理器,容器化部署、弹性伸缩方便,是云原生趋势,目前生产环境普及度逐步提升
2.5 部署模式对比总结
| 模式 | Cluster Manager | 适用场景 | 学习优先级 |
|---|---|---|---|
| Local | 无(本地单JVM) | 开发调试、入门学习 | ⭐⭐⭐⭐⭐ 第一个学 |
| Standalone | Spark自带 | 学习集群原理、纯Spark集群 | ⭐⭐⭐⭐ 重点学原理 |
| YARN | Hadoop YARN | 企业生产环境(最主流) | ⭐⭐⭐⭐⭐ 必须掌握 |
| Mesos | Apache Mesos | 国内少用 | ⭐ 了解 |
| K8s | Kubernetes | 云原生、容器化 | ⭐⭐ 了解趋势 |
第三部分:环境搭建实操(3个核心任务)
任务一:Local 本地模式搭建(最简入门)
最简单的模式,解压+配置环境变量就能用,适合快速入门。
步骤1:解压Spark安装包
cd /root
# 解压到/usr/local目录
tar -zxf spark-3.5.1-bin-hadoop3-scala2.13.tgz -C /usr/local/
# 重命名为简化路径
mv /usr/local/spark-3.5.1-bin-hadoop3-scala2.13 /usr/local/spark步骤2:配置全局环境变量
cat >> /etc/profile << 'EOF'
# Spark Environment
export SPARK_HOME=/usr/local/spark
export PATH=$SPARK_HOME/bin:$SPARK_HOME/sbin:$PATH
EOF
# 立即生效
source /etc/profile
步骤3:验证Local模式
# 启动spark-shell(默认就是local[*]模式)
spark-shell✅ 验证标准:出现 scala> 提示符即为启动成功。 退出输入::quit

任务二:Standalone 单机伪分布式搭建
伪分布式:只有一台机器,但模拟了 Master + Worker 的完整集群架构,适合学习集群原理。
步骤1:配置 spark-env.sh
cd $SPARK_HOME/conf
# 从模板复制配置文件
cp spark-env.sh.template spark-env.sh
# 编辑配置
vi spark-env.sh在文件末尾添加以下内容:
# JDK路径(必须配置)
export JAVA_HOME=/usr/local/jdk1.8.0_461
# Hadoop配置(读写HDFS、跑YARN时需要)
export HADOOP_HOME=/usr/local/hadoop-3.3.6
export HADOOP_CONF_DIR=/usr/local/hadoop-3.3.6/etc/hadoop
# Master节点地址
export SPARK_MASTER_IP=master
export SPARK_LOCAL_IP=master步骤2:启动Spark单机集群
cd $SPARK_HOME/sbin
# 启动所有(Master + Worker)
./start-all.sh步骤3:进程验证
jps✅ 预期进程:Master、Worker 两个Spark进程。

步骤4:Web UI查看
浏览器访问:http://192.168.128.130:8080 可查看集群状态、Worker数量、总资源、运行的应用。

步骤5:运行测试案例——SparkPi
# 运行官方示例,2个分区
$SPARK_HOME/bin/run-example SparkPi 2✅ 验证标准:输出结果包含 Pi is roughly 3.14...,说明伪分布式搭建成功。

任务三:Standalone 完全分布式集群搭建(核心重点)
三节点集群:master(主)+ slave1(从)+ slave2(从),是面试常考实操题。
3.1 整体角色规划
| 节点 | 进程 |
|---|---|
| master | Master、Worker、HistoryServer |
| slave1 | Worker |
| slave2 | Worker |

3.2 详细操作步骤
步骤1:配置 spark-env.sh(master节点操作)
cd $SPARK_HOME/conf
cp spark-env.sh.template spark-env.sh
vi spark-env.sh完整配置内容:
# 1. JDK路径:所有Java程序必需
export JAVA_HOME=/usr/local/jdk1.8.0_461
# 2. Hadoop相关:读写HDFS、提交YARN必需
export HADOOP_HOME=/usr/local/hadoop-3.3.6
export HADOOP_CONF_DIR=/usr/local/hadoop-3.3.6/etc/hadoop
export LD_LIBRARY_PATH=$HADOOP_HOME/lib/native
# 3. Master配置
export SPARK_MASTER_IP=master
export SPARK_MASTER_PORT=7077
# 4. Worker资源配置(教学环境调小,生产环境按实际配置)
export SPARK_WORKER_MEMORY=2g
export SPARK_WORKER_CORES=2
export SPARK_WORKER_INSTANCES=1
# 5. Executor资源配置
export SPARK_EXECUTOR_MEMORY=1g
export SPARK_EXECUTOR_CORES=1💡 配置说明:
SPARK_WORKER_MEMORY:每个Worker节点能给Spark用的总内存SPARK_WORKER_CORES:每个Worker节点能给Spark用的CPU核数SPARK_WORKER_INSTANCES:每台机器启动的Worker进程数,一般1个即可
步骤2:配置 workers 文件(指定工作节点)
workers 文件用来定义哪些节点是Worker节点(Spark 2.x叫slaves文件)。
cd $SPARK_HOME/conf
cp workers.template workers
vi workers删除原有内容,添加三台节点主机名(每行一个):
master
slave1
slave2说明:教学环境master也兼做Worker,充分利用资源;生产环境建议Master只做调度,不参与计算。

步骤3:配置 spark-defaults.conf(默认参数)
配置应用默认参数,避免每次提交都手动写参数。
cd $SPARK_HOME/conf
cp spark-defaults.conf.template spark-defaults.conf
vi spark-defaults.conf添加以下内容:
# 默认提交到Standalone集群
spark.master spark://master:7077
# 开启事件日志,HistoryServer才能读取
spark.eventLog.enabled true
spark.eventLog.dir hdfs:///spark-logs
# HistoryServer日志目录
spark.history.fs.logDirectory hdfs:///spark-logs
# Kryo序列化,提升性能
spark.serializer org.apache.spark.serializer.KryoSerializer步骤4:分发安装包与配置到从节点
# 1. 分发完整Spark安装目录
scp -r /usr/local/spark root@slave1:/usr/local/
scp -r /usr/local/spark root@slave2:/usr/local/
# 2. 同步全局环境变量
scp /etc/profile root@slave1:/etc/
scp /etc/profile root@slave2:/etc/
# 3. 从节点生效环境变量
ssh slave1 "source /etc/profile"
ssh slave2 "source /etc/profile"
步骤5:启动Hadoop集群(必须先启动)
事件日志存在HDFS上,必须先启动Hadoop。
cd $HADOOP_HOME/sbin
./start-all.sh步骤6:HDFS创建事件日志目录
hdfs dfs -mkdir -p /spark-logs
hdfs dfs -chmod 777 /spark-logs步骤7:启动Spark完全分布式集群
cd $SPARK_HOME/sbin
# 启动Master + 所有Worker
./start-all.sh
# 启动历史服务器
./start-history-server.sh步骤8:集群验证(三种方法)
方法一:进程验证
# master节点
jps
# 预期:Master、Worker、HistoryServer
# 验证 slave1 节点
ssh slave1 "/usr/local/jdk1.8.0_461/bin/jps"
# 预期:Worker
# 验证 slave2 节点
ssh slave2 "/usr/local/jdk1.8.0_461/bin/jps"
# 预期:Worker方法二:Web UI验证
- Master Web UI(实时集群监控):
http://192.168.128.130:8080作用:查看Worker节点列表、集群总资源、运行/完成的应用 说明:只有Standalone模式有此界面,YARN模式没有

- HistoryServer Web UI(历史作业监控):
http://192.168.128.130:18080作用:查看所有历史作业、运行日志 说明:需要开启事件日志并启动HistoryServer

方法三:运行测试程序
# 运行SparkPi示例,2个分区
$SPARK_HOME/bin/run-example SparkPi 2✅ 验证标准:正常输出Pi的近似值,说明完全分布式集群搭建成功。

3.3 集群启停命令汇总
| 类型 | 命令 | 作用 |
|---|---|---|
| 启动 | start-all.sh | 启动所有(Master + 所有Worker) |
| 启动 | start-master.sh | 只启动Master |
| 启动 | start-worker.sh spark://master:7077 | 只启动Worker(从节点执行) |
| 启动 | start-history-server.sh | 启动历史服务器 |
| 停止 | stop-all.sh | 停止所有 |
| 停止 | stop-master.sh | 只停止Master |
| 停止 | stop-worker.sh | 只停止Worker |
| 停止 | stop-history-server.sh | 停止历史服务器 |
3.4 spark-shell 常用启动方式
# 1. Local模式(默认)
spark-shell
# 等价于
spark-shell --master local[*]
# 2. 指定资源启动
spark-shell --executor-memory 512m --total-executor-cores 3
# 3. Standalone模式
spark-shell --master spark://master:7077
# 4. YARN Client模式
spark-shell --master yarn --deploy-mode client⚠️ 注意:spark-shell 不能用 YARN Cluster 模式!交互式需要Driver在本地。
第四部分:YARN模式实操(企业生产标准)
1.1 为什么企业都用 YARN 模式?
Standalone 是 Spark 自带的轻量集群管理器,只适合纯 Spark 技术栈的小规模场景;而企业大数据平台通常是 Hadoop 生态全家桶(HDFS + YARN + Hive + Spark + Flink 等),因此统一用 YARN 做整个集群的资源管理器,核心优势:
- 资源统一管理:Hadoop、Hive、Spark 共用一套集群资源,不用维护多套独立集群,资源利用率更高
- 调度能力成熟:YARN 自带队列管理、容量调度、资源隔离、任务优先级等机制,更适合多业务生产环境
- 运维成本低:一套集群运维,生态打通,权限、监控、日志体系统一
- 生态兼容性强:和 Hive、HBase、Sqoop 等组件无缝联动,数据共享成本低
1.2 和 Standalone 模式的本质区别
| 维度 | Standalone 模式 | YARN 模式 |
|---|---|---|
| 资源管理器 | Spark 自带 Master | Hadoop YARN(ResourceManager) |
| 常驻进程 | Master、Worker 全程运行 | 无常驻 Spark 进程,任务启动时由 YARN 生成容器 |
| 资源粒度 | 按 Worker 节点预分配 | 按任务动态分配 Container,用完释放 |
| 生态适配 | 仅 Spark 生态 | 兼容整个 Hadoop 生态 |
| 生产定位 | 小规模、纯 Spark 场景 | 企业级大数据平台标准 |
✅ 两种模式共用同一套 Spark 安装包、同一份配置,只是提交任务时通过
--master参数切换调度器,无技术冲突,可无缝切换。
二、核心原理
2.1 YARN 模式整体架构
Spark 作为 YARN 的一个客户端应用,运行时向 YARN 申请资源,由 YARN 的 NodeManager 启动 Executor 容器运行计算:
- ResourceManager(RM):YARN 全局资源管理器,负责整个集群的资源分配
- NodeManager(NM):节点级资源管理器,负责启动 / 管理 Container
- ApplicationMaster(AM):每个 Spark 任务对应一个 AM,负责向 RM 申请 Executor 资源
- Executor:运行在 Container 里的计算进程,负责执行 Task
- Driver:解析代码、生成 DAG、调度 Task 的驱动程序

2.2 两种部署模式:Client vs Cluster
这是 YARN 模式最核心的知识点,也是面试高频考点。
对比表
| 对比项 | YARN Client 模式 | YARN Cluster 模式 |
|---|---|---|
| Driver 运行位置 | 提交任务的客户端机器上 | YARN 集群的 ApplicationMaster 容器内 |
| 客户端断开 | 作业立即终止 | 作业继续在后台运行 |
| 日志查看 | 直接在客户端终端输出 | 需要从 YARN UI / 日志服务器查看 |
| AM 职责 | 只负责申请资源 | 申请资源 + 运行 Driver + 监督作业 |
| 优点 | 调试方便,日志实时看 | 稳定可靠,适合后台运行 |
| 适用场景 | 调试、交互式终端(spark-shell /pyspark) | 生产环境批处理任务、后台作业 |
⚠️ 重要结论:
spark-shell、pyspark只能用 Client 模式!因为交互式需要 Driver 在本地和用户实时交互。
运行流程(Cluster 模式,6 步)
- 客户端提交 Spark 应用程序
- ResourceManager 接收请求,选中一台 NodeManager 启动 ApplicationMaster
- ApplicationMaster 内部启动 Driver Program(驱动程序)
- ApplicationMaster 向 ResourceManager 申请 Executor 资源
- ResourceManager 分配资源,在各 NodeManager 上启动 Container + Executor
- Driver 将 Task 分发到各 Executor 执行,Executor 向 Driver 注册并汇报进度
4.1 前置说明
- 无需启动Spark的Master、Worker进程,只要YARN集群正常即可
- Spark应用作为YARN的作业运行,资源由YARN统一调度
- 和阿里云EMR集群运行方式完全一致
4.2 提交批处理测试任务
# 提交SparkPi到YARN,客户端模式
spark-submit --master yarn --deploy-mode client \
--class org.apache.spark.examples.SparkPi \
$SPARK_HOME/examples/jars/spark-examples_2.13-3.5.1.jar \
100✅ 验证:终端最终输出 Pi is roughly 3.xxxxxx。

4.3 交互式终端
# Python版
pyspark --master yarn
# Scala版
spark-shell --master yarn4.4 监控查看
- YARN ResourceManager UI:
http://192.168.128.130:8088查看所有应用列表、状态、资源使用 - Spark Driver UI:点击YARN任务中的Tracking URL,查看DAG、Stage、Executor、Shuffle详情


第五部分:Spark初体验:WordCount & SparkPi
5.1 WordCount(词频统计)——Spark的HelloWorld
准备测试数据
# 本地创建测试文件
cat > words.txt << 'EOF'
hello spark hello hadoop
spark is fast hadoop is stable
spark sql spark streaming
EOF
# 上传到HDFS
hdfs dfs -mkdir -p /test
hdfs dfs -put words.txt /test/Scala版本(spark-shell中执行)
// 读取HDFS文件 → 分词 → 映射 → 聚合 → 打印
sc.textFile("/test/words.txt")
.flatMap(_.split(" "))
.map((_, 1))
.reduceByKey(_ + _)
.collect()
.foreach(println)Python版本(pyspark中执行)
lines = sc.textFile("/test/words.txt")
word_count = lines.flatMap(lambda line: line.split(" ")) \
.map(lambda word: (word, 1)) \
.reduceByKey(lambda a, b: a + b)
print(word_count.collect())💡 原理说明:
flatMap/map是转换算子,只构建依赖链,不触发计算reduceByKey是宽依赖,触发Shuffle,是Stage划分边界collect()是行动算子,触发整个Job执行
5.2 SparkPi 圆周率计算
Spark自带示例,用蒙特卡洛算法计算圆周率。
# 2个分区
$SPARK_HOME/bin/run-example SparkPi 2
# 100个分区(精度更高,并行度更高)
$SPARK_HOME/bin/run-example SparkPi 100原理:正方形内画内切圆,随机扔点,统计圆内点的比例,π ≈ 4 × 比例;分区越多,并行度越高,结果越精确。