Spark On Yarn 集群搭建

前置准备

在开始搭建 Spark on YARN 集群之前,请确保以下条件已满足:

  • 三台节点(masterslave1slave2)之间已配置 SSH 免密登录;
  • 三台节点的 /etc/hosts 已配置主机名与 IP 的映射关系;
  • Hadoop 3.1.4 集群已部署完成,且 YARN 的 ResourceManager 运行在 slave1 节点;
  • JDK 1.8 已安装并配置好 JAVA_HOME 环境变量。

💡 若尚未完成 Hadoop 集群部署,请先参考 Hadoop 集群搭建文档,确保 HDFS 与 YARN 均能正常启动。
环境信息

  • Spark:spark‑3.0.3‑bin‑hadoop3.2
  • Hadoop:hadoop‑3.1.4
  • JDK:jdk1.8.0_161
  • 集群节点:masterslave1slave2

💡说Spark on YARN 不需要启动 Spark 自身 Master、Worker 进程**,资源全部由 YARN 调仅需启动 Spark 历史服务器,用于查看已完成任务日志。。。

1. 解压 Spark 安装包(master 节点执行)))

复制代码
# 进入压缩包存放目录
cd /opt/software# 解压到 /opt/modulele
tar -zxvf spark-3.0.3-bin-hadoop3.2.tgz -C /opt/module/

# 进入安装目录,重命名
cd /opt/modul
mv spark-3.0.3-bin-hadoop3.2 sparkonyarn

2. 配置全局环境变量(master 节点)))

复制代码
vi /etc/profile.d/my_env.sh

写入下面内容:

复制代码
export SPARK_HOME=/opt/module/sparkonyarn
export PATH=$PATH:$SPARK_HOME/bin:$SPARK_HOME/sbin


保存退出,后续同步该文件到 slave 节点。

3. 修改 YARN 配置文件 yarn-site.xml(master 节点)))

复制代码
vi /opt/module/hadoop-3.1.4/etc/hadoop/yarn-site.xml
在 `<configuration>` 标签内添加配置:

``<!-- YARN WebUI 绑定所有 IP,解决宿主机无法访问 8088 页面 -->->
<property>
    <name>yarn.resourcemanager.webapp.address</name>
    <value>slave1:8088</value>
</property>

<!-- 关闭物理内存检查 -->
<property>
    <name>yarn.nodemanager.pmem-check-enabled</name>
    <value>false</value>
</property>

<!-- 物理内存:虚拟内存 = 1:4 -->
<property>
    <name>yarn.nodemanager.vmem-pmem-ratio</name>
    <value>4</value>
</property>

<!-- 关闭虚拟内存检查,避免测试程序被yarn杀掉 -->
<property>
    <name>yarn.nodemanager.vmem-check-enabled</name>
    <value>false</value>
</property>

⚠️提示:生产环境不建议关闭内存检查,仅测试环境使用。

4. 修改 Spark 配置文件(master 节点))

复制代码
cd /opt/module/sparkonyarn/conf

5. 配置 slaves 从节点列表

复制代码
mv slaves.template slaves
vi slaves

写入主机名:

复制代码
master
slave1
slave2

on-yarn 任务本身不读取 slaveses,主要供历史服务器使用。

6. 修改 spark-env.sh

复制代码
mv spark-env.sh.template spark-env.sh
vi spark-env.sh

追加内容:

`

bash 复制代码
`# JDK 路径路径
JAVA_HOME=/opt/module/jdk1.8.0_161
# 对接 YARN 核心配置配置
HADOOP_CONF_DIR=/opt/module/hadoop-3.1.4/etc/hadoop
YARN_CONF_DIR=/opt/module/hadoop-3.1.4/etc/hadoop
# Spark 历史服务器配置配置
export SPARK_HISTORY_OPTS="
-Dspark.history.ui.port=18080
-Dspark.history.fs.logDirectory=hdfs://master:8020/directory
-Dspark.history.retainedApplications=30"

参数说明:

参数 作用
spark.history.ui.port 历史服务 Web 端口 18080
spark.history.fs.logDirectory 任务日志保存到 HDFS 路径
spark.history.retainedApplications 保留 30 个任务 UI 缓存

7.修改 spark-defaults.conf

bash 复制代码
mv spark-defaults.conf.template spark-defaults.conf
vi spark-defaults.conf

写入配置:

复制代码
# 开启事件日志
spark.eventLog.enabled true
# 日志 HDFS 存储路径路径
spark.eventLog.dir hdfs://master:8020/directory
# 历史服务器地址
spark.yarn.historyServer.address master:18080
spark.history.ui.port 18080

✅ 必须提前在 HDFS 创建日志目录,否则历史服务器启动失败。失败

复制代码
hdfs dfs -mkdir -p /directory
hdfs dfs -chmod 777 /directory

8. 同步所有配置到 slave1、slave2(master 执行)

8.1 同步环境变量

复制代码
scp -r /etc/profile.d/my_env.sh slave1:/etc/profile.d/
scp -r /etc/profile.d/my_env.sh slave2:/etc/profile.d/

📌 slave1、slave2 两台机器分别执行,使环境变量生效

bash 复制代码
source /etc/profile.d/my_env.sh

8.2 同步 Spark on YARN 整个安装目录装目录

bash 复制代码
scp -r /opt/module/sparkonyarn slave1:/opt/module/
scp -r /opt/module/sparkonyarn slave2:/opt/module/

8.3 同步 YARN-site.xml

bash 复制代码
scp -r /opt/module/hadoop-3.1.4/etc/hadoop/yarn-site.xml slave1:/opt/module/hadoop-3.1.4/etc/hadoop/
scp -r /opt/module/hadoop-3.1.4/etc/hadoop/yarn-site.xml slave2:/opt/module/hadoop-3.1.4/etc/hadoop/

配置同步流程如下:
#mermaid-svg-wh3jx7Enc7AesRae{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-wh3jx7Enc7AesRae .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-wh3jx7Enc7AesRae .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-wh3jx7Enc7AesRae .error-icon{fill:#552222;}#mermaid-svg-wh3jx7Enc7AesRae .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-wh3jx7Enc7AesRae .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-wh3jx7Enc7AesRae .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-wh3jx7Enc7AesRae .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-wh3jx7Enc7AesRae .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-wh3jx7Enc7AesRae .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-wh3jx7Enc7AesRae .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-wh3jx7Enc7AesRae .marker{fill:#333333;stroke:#333333;}#mermaid-svg-wh3jx7Enc7AesRae .marker.cross{stroke:#333333;}#mermaid-svg-wh3jx7Enc7AesRae svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-wh3jx7Enc7AesRae p{margin:0;}#mermaid-svg-wh3jx7Enc7AesRae .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-wh3jx7Enc7AesRae .cluster-label text{fill:#333;}#mermaid-svg-wh3jx7Enc7AesRae .cluster-label span{color:#333;}#mermaid-svg-wh3jx7Enc7AesRae .cluster-label span p{background-color:transparent;}#mermaid-svg-wh3jx7Enc7AesRae .label text,#mermaid-svg-wh3jx7Enc7AesRae span{fill:#333;color:#333;}#mermaid-svg-wh3jx7Enc7AesRae .node rect,#mermaid-svg-wh3jx7Enc7AesRae .node circle,#mermaid-svg-wh3jx7Enc7AesRae .node ellipse,#mermaid-svg-wh3jx7Enc7AesRae .node polygon,#mermaid-svg-wh3jx7Enc7AesRae .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-wh3jx7Enc7AesRae .rough-node .label text,#mermaid-svg-wh3jx7Enc7AesRae .node .label text,#mermaid-svg-wh3jx7Enc7AesRae .image-shape .label,#mermaid-svg-wh3jx7Enc7AesRae .icon-shape .label{text-anchor:middle;}#mermaid-svg-wh3jx7Enc7AesRae .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-wh3jx7Enc7AesRae .rough-node .label,#mermaid-svg-wh3jx7Enc7AesRae .node .label,#mermaid-svg-wh3jx7Enc7AesRae .image-shape .label,#mermaid-svg-wh3jx7Enc7AesRae .icon-shape .label{text-align:center;}#mermaid-svg-wh3jx7Enc7AesRae .node.clickable{cursor:pointer;}#mermaid-svg-wh3jx7Enc7AesRae .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-wh3jx7Enc7AesRae .arrowheadPath{fill:#333333;}#mermaid-svg-wh3jx7Enc7AesRae .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-wh3jx7Enc7AesRae .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-wh3jx7Enc7AesRae .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-wh3jx7Enc7AesRae .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-wh3jx7Enc7AesRae .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-wh3jx7Enc7AesRae .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-wh3jx7Enc7AesRae .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-wh3jx7Enc7AesRae .cluster text{fill:#333;}#mermaid-svg-wh3jx7Enc7AesRae .cluster span{color:#333;}#mermaid-svg-wh3jx7Enc7AesRae div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-wh3jx7Enc7AesRae .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-wh3jx7Enc7AesRae rect.text{fill:none;stroke-width:0;}#mermaid-svg-wh3jx7Enc7AesRae .icon-shape,#mermaid-svg-wh3jx7Enc7AesRae .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-wh3jx7Enc7AesRae .icon-shape p,#mermaid-svg-wh3jx7Enc7AesRae .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-wh3jx7Enc7AesRae .icon-shape .label rect,#mermaid-svg-wh3jx7Enc7AesRae .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-wh3jx7Enc7AesRae .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-wh3jx7Enc7AesRae .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-wh3jx7Enc7AesRae :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} master 节点

修改配置文件
同步环境变量

my_env.sh
同步安装目录

sparkonyarn
同步 YARN 配置

yarn-site.xml
slave1 执行 source
slave2 执行 source
slave1 生效
slave2 生效
slave1 生效
slave2 生效

`

9. 启动集群服务

启动顺序:HDFS → YARN → Spark 历史服务器服务器

bash 复制代码
`# master 节点启动 Hadoopoop
start-dfs.sh
start-yarn.sh
# 启动 Spark 历史服务器服务器
cd /opt/module/sparkonyarn/sbin
./start-history-server.sh

`

访问 Web 页面b页面

`

10. 提交Spark任务

10.1 --deploy-mode client 客户端模式

Driver 运行在提交任务的客户端机器(master),适合调试,日志直接打印控制台。控制台

复制代码
spark-submit --class org.apache.spark.examples.SparkPi \
--master yarn \
--deploy-mode client \
/opt/module/sparkonyarn/examples/jars/spark-examples_2.12-3.0.3.jar 10

10.2 --deploy-mode cluster 集群模式

Driver 运行在 YARN 容器内部(NodeManager 节点),生产环境推荐;控制台看不到 Driver 日志,需要去 YARN/历史服务器查看日志看日志

复制代码
spark-submit --class org.apache.spark.examples.SparkPi \
--master yarn \
--deploy-mode cluster \
/opt/module/sparkonyarn/examples/jars/spark-examples_2.12-3.0.3.jar 10

client 与 cluster 模式对比式对比

模式 Driver 进程位置 适用场景 日志查看
client 提交任务的客户端节点(master) 开发调试 控制台直接输出 Driver 日志
cluster YARN 容器(NodeManager) 生产环境 YARN UI / Spark 历史服务器查看日志
两种部署模式的任务提交流程对比如下:

10.3 client 模式提交流程

  1. 客户端(master)启动 SparkSubmit 进程,在本地创建 Driver
  2. Driver 向 YARN 的 ResourceManager 申请资源,提交 Application;
  3. ResourceManager 在某个 NodeManager 节点上启动 ApplicationMaster(AM)
  4. AM 向 ResourceManager 申请 Executor 所需的容器资源;
  5. ResourceManager 分配容器,AM 在对应 NodeManager 上启动 Executor
  6. Executor 反向注册到客户端本地的 Driver,Driver 分发任务并收集结果;
  7. 任务完成后,Driver 在客户端控制台直接打印计算结果(如 Pi is roughly ...)。

10.4 cluster 模式提交流程

  1. 客户端(master)仅启动 SparkSubmit 进程,不创建 Driver,只负责提交 Application;
  2. SparkSubmit 向 YARN 的 ResourceManager 提交 Application;
  3. ResourceManager 在某个 NodeManager 节点上启动 ApplicationMaster(AM)Driver 运行在 AM 内部
  4. AM 向 ResourceManager 申请 Executor 所需的容器资源;
  5. ResourceManager 分配容器,AM 在对应 NodeManager 上启动 Executor
  6. Executor 反向注册到 AM 内部的 Driver,Driver 分发任务并收集结果;
  7. 任务完成后,客户端控制台不会打印计算结果,需通过 YARN WebUI 或 Spark 历史服务器查看日志。

两种模式的任务提交流程对比图:
#mermaid-svg-DE5tz4LPSDlNYG0v{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-DE5tz4LPSDlNYG0v .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-DE5tz4LPSDlNYG0v .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-DE5tz4LPSDlNYG0v .error-icon{fill:#552222;}#mermaid-svg-DE5tz4LPSDlNYG0v .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-DE5tz4LPSDlNYG0v .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-DE5tz4LPSDlNYG0v .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-DE5tz4LPSDlNYG0v .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-DE5tz4LPSDlNYG0v .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-DE5tz4LPSDlNYG0v .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-DE5tz4LPSDlNYG0v .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-DE5tz4LPSDlNYG0v .marker{fill:#333333;stroke:#333333;}#mermaid-svg-DE5tz4LPSDlNYG0v .marker.cross{stroke:#333333;}#mermaid-svg-DE5tz4LPSDlNYG0v svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-DE5tz4LPSDlNYG0v p{margin:0;}#mermaid-svg-DE5tz4LPSDlNYG0v .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-DE5tz4LPSDlNYG0v .cluster-label text{fill:#333;}#mermaid-svg-DE5tz4LPSDlNYG0v .cluster-label span{color:#333;}#mermaid-svg-DE5tz4LPSDlNYG0v .cluster-label span p{background-color:transparent;}#mermaid-svg-DE5tz4LPSDlNYG0v .label text,#mermaid-svg-DE5tz4LPSDlNYG0v span{fill:#333;color:#333;}#mermaid-svg-DE5tz4LPSDlNYG0v .node rect,#mermaid-svg-DE5tz4LPSDlNYG0v .node circle,#mermaid-svg-DE5tz4LPSDlNYG0v .node ellipse,#mermaid-svg-DE5tz4LPSDlNYG0v .node polygon,#mermaid-svg-DE5tz4LPSDlNYG0v .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-DE5tz4LPSDlNYG0v .rough-node .label text,#mermaid-svg-DE5tz4LPSDlNYG0v .node .label text,#mermaid-svg-DE5tz4LPSDlNYG0v .image-shape .label,#mermaid-svg-DE5tz4LPSDlNYG0v .icon-shape .label{text-anchor:middle;}#mermaid-svg-DE5tz4LPSDlNYG0v .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-DE5tz4LPSDlNYG0v .rough-node .label,#mermaid-svg-DE5tz4LPSDlNYG0v .node .label,#mermaid-svg-DE5tz4LPSDlNYG0v .image-shape .label,#mermaid-svg-DE5tz4LPSDlNYG0v .icon-shape .label{text-align:center;}#mermaid-svg-DE5tz4LPSDlNYG0v .node.clickable{cursor:pointer;}#mermaid-svg-DE5tz4LPSDlNYG0v .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-DE5tz4LPSDlNYG0v .arrowheadPath{fill:#333333;}#mermaid-svg-DE5tz4LPSDlNYG0v .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-DE5tz4LPSDlNYG0v .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-DE5tz4LPSDlNYG0v .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-DE5tz4LPSDlNYG0v .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-DE5tz4LPSDlNYG0v .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-DE5tz4LPSDlNYG0v .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-DE5tz4LPSDlNYG0v .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-DE5tz4LPSDlNYG0v .cluster text{fill:#333;}#mermaid-svg-DE5tz4LPSDlNYG0v .cluster span{color:#333;}#mermaid-svg-DE5tz4LPSDlNYG0v div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-DE5tz4LPSDlNYG0v .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-DE5tz4LPSDlNYG0v rect.text{fill:none;stroke-width:0;}#mermaid-svg-DE5tz4LPSDlNYG0v .icon-shape,#mermaid-svg-DE5tz4LPSDlNYG0v .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-DE5tz4LPSDlNYG0v .icon-shape p,#mermaid-svg-DE5tz4LPSDlNYG0v .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-DE5tz4LPSDlNYG0v .icon-shape .label rect,#mermaid-svg-DE5tz4LPSDlNYG0v .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-DE5tz4LPSDlNYG0v .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-DE5tz4LPSDlNYG0v .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-DE5tz4LPSDlNYG0v :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} cluster 模式
客户端 SparkSubmit

仅提交 Application
向 ResourceManager 提交 Application
ResourceManager 启动 ApplicationMaster

Driver 运行在 AM 内部
AM 申请容器资源
NodeManager 启动 Executor
Executor 注册到 AM 内 Driver
通过 YARN WebUI / 历史服务器查看日志
client 模式
客户端 SparkSubmit

启动本地 Driver
向 ResourceManager 提交 Application
ResourceManager 启动 ApplicationMaster
AM 申请容器资源
NodeManager 启动 Executor
Executor 注册到本地 Driver
控制台直接输出结果

📌 核心区别:client 模式 Driver 在客户端本地,cluster 模式 Driver 在 YARN 容器内 。因此 client 模式便于调试、日志直接打印;cluster 模式适合生产环境,日志需到 YARN/历史服务器查看。

对比:

🔧 常见问题排查

1. 历史服务器启动报错:HDFS 日志目录不存在

现象 :执行 ./start-history-server.sh 后,日志报错 org.apache.hadoop.ipc.RemoteException: org.apache.hadoop.hdfs.protocol.FSException: File /directory does not exist

原因spark-defaults.conf 中配置的 spark.eventLog.dir 指向的 HDFS 目录尚未创建。

解决 :在 master 节点执行以下命令创建目录并授权:

bash 复制代码
hdfs dfs -mkdir -p /directory
hdfs dfs -chmod 777 /directory

✅ 创建完成后重启历史服务器即可正常启动。

2. YARN 任务报虚拟内存被 kill

现象 :提交 Spark 任务后,任务运行一段时间被 YARN 强制终止,日志中出现 Container killed by YARN for exceeding memory limits

原因:YARN 默认开启物理内存和虚拟内存检查,测试环境下容易误杀任务。

解决 :确认 yarn-site.xml 中以下两个配置均为 false

xml 复制代码
<property>
    <name>yarn.nodemanager.pmem-check-enabled</name>
    <value>false</value>
</property>
<property>
    <name>yarn.nodemanager.vmem-check-enabled</name>
    <value>false</value>
</property>

⚠️ 修改后需重启 YARN 集群使配置生效。

3. WebUI 无法访问

现象 :浏览器无法访问 YARN WebUI(http://slave1:8088)或 Spark 历史服务器(http://master:18080)。

原因 :常见原因包括防火墙未关闭、/etc/hosts 主机名映射错误、yarn-site.xmlyarn.resourcemanager.webapp.address 配置错误。

解决

bash 复制代码
# 关闭防火墙(三台节点均执行)
systemctl stop firewalld
systemctl disable firewalld

# 检查 /etc/hosts 是否包含三台节点的主机名与 IP 映射
cat /etc/hosts

📌 确认 yarn-site.xmlyarn.resourcemanager.webapp.address 已配置为 slave1:8088,且所有节点配置已同步。

4. Spark 无法连接 YARN

现象 :提交任务时报错 ApplicationMaster is not registeredFailed to connect to resource manager

原因HADOOP_CONF_DIRYARN_CONF_DIR 路径配置错误,或各节点配置未同步。

解决

bash 复制代码
# 确认 spark-env.sh 中路径正确
echo $HADOOP_CONF_DIR
echo $YARN_CONF_DIR

# 确认所有节点配置已同步
scp -r /opt/module/hadoop-3.1.4/etc/hadoop/yarn-site.xml slave1:/opt/module/hadoop-3.1.4/etc/hadoop/
scp -r /opt/module/hadoop-3.1.4/etc/hadoop/yarn-site.xml slave2:/opt/module/hadoop-3.1.4/etc/hadoop/

📌 修改配置后需在 master 节点重启 YARN 集群,并在 slave1slave2 节点执行 source /etc/profile.d/my_env.sh 使环境变量生效。

5. 提交任务报 ClassNotFoundException

现象 :提交 SparkPi 任务时报错 java.lang.ClassNotFoundException: org.apache.spark.examples.SparkPi

原因spark-examples_2.12-3.0.3.jar 路径错误或文件不存在。

解决

bash 复制代码
# 确认示例 jar 包存在
ls -l /opt/module/sparkonyarn/examples/jars/spark-examples_2.12-3.0.3.jar

# 若不存在,检查 Spark 安装目录是否完整
ls /opt/module/sparkonyarn/examples/jars/
``

### 6. 端口被占用

**现象**:启动历史服务器或提交任务时报错 `Address already in use`,或 WebUI 无法打开。

**原因**:`18080`、`8088`、`9870` 等端口被其他进程占用,或上次异常退出后端口未释放。

**解决**:

```bash
# 查看端口占用情况
netstat -tlnp | grep 18080
netstat -tlnp | grep 8088

# 找到占用进程后,kill 掉对应 PID
kill -9 <PID>

📌 若端口被频繁占用,可在 spark-env.sh 中调整 spark.history.ui.port 为其他可用端口(如 18081)。

7. 任务提交后一直 ACCEPTED 不运行

现象 :提交 Spark 任务后,YARN WebUI 中任务状态长时间停留在 ACCEPTED,迟迟不进入 RUNNING

原因 :常见原因包括集群资源不足(内存/CPU 被占满)、yarn-site.xmlyarn.scheduler.maximum-allocation-mb 配置过小、或 NodeManager 未正常启动。

解决

bash 复制代码
# 检查 NodeManager 是否全部启动(三台节点均执行)
jps

# 查看 YARN 资源使用情况
yarn node -list -all

# 查看集群可用资源
yarn application -list

📌 若资源不足,可适当调大 yarn-site.xml 中的 yarn.scheduler.maximum-allocation-mbyarn.nodemanager.resource.memory-mb,并重启 YARN 集群。

8. Executor 启动失败

现象 :任务提交后,日志中出现 ExecutorLostFailureContainer exited with a non-zero exit code

原因:常见原因包括 Executor 内存配置过大超出容器限制、JVM 参数错误、或节点磁盘空间不足。

解决

bash 复制代码
# 提交任务时显式指定 Executor 内存和核数
spark-submit --class org.apache.spark.examples.SparkPi \
--master yarn \
--deploy-mode cluster \
--executor-memory 1g \
--executor-cores 1 \
--num-executors 2 \
/opt/module/sparkonyarn/examples/jars/spark-examples_2.12-3.0.3.jar 10

📌 确认 spark-defaults.confspark.executor.memory 不超过 yarn.nodemanager.resource.memory-mb 的可用值,并检查各节点磁盘空间(df -h)。

9. 历史服务器无法访问

现象 :浏览器无法打开 Spark 历史服务器页面(http://master:18080),或页面显示无任务记录。

原因 :历史服务器未启动、spark.eventLog.dirspark.history.fs.logDirectory 配置不一致、或 HDFS 日志目录权限不足。

解决

bash 复制代码
# 确认历史服务器进程已启动
jps

# 确认 spark-defaults.conf 与 spark-env.sh 中日志目录配置一致
grep -r "logDirectory\|eventLog.dir" /opt/module/sparkonyarn/conf/

# 确认 HDFS 日志目录存在且有写权限
hdfs dfs -ls /directory
hdfs dfs -chmod 777 /directory

📌 若配置不一致,统一修改后重启历史服务器;若 HDFS 目录无权限,执行 hdfs dfs -chmod 777 /directory 授权。

10. 磁盘空间不足

现象 :任务运行中报错 No space left on device,或 HDFS 写入失败。

原因:Spark 事件日志、YARN 容器日志或 HDFS 数据块占满磁盘。

解决

bash 复制代码
# 查看各节点磁盘使用情况
df -h

# 清理 Spark 历史日志目录(谨慎操作)
hdfs dfs -rm -r /directory/*

# 清理 YARN 本地日志
rm -rf /opt/module/hadoop-3.1.4/logs/userlogs/*

📌 生产环境建议配置日志滚动与定期清理策略,避免日志无限增长占满磁盘。

`
📌 若 jar 包缺失,需重新解压 Spark 安装包并同步到所有节点。

步完成

11. 验证集群是否可用

集群搭建完成后,建议按以下步骤验证集群是否真正可用,确保后续任务能正常提交运行。

9.1 检查关键进程(master 节点执行)

master 节点执行 jps,确认以下进程均已启动:

bash 复制代码
jps

预期输出(关键进程):

bash 复制代码
12345 NameNode
12346 DataNode
12348 NodeManager
12349 HistoryServer

📌 说明:

  • ResourceManager 运行在 slave1 节点,因此 master 节点的 jps不会 出现 ResourceManager,需到 slave1 节点执行 jps 确认;
  • master 节点应能看到 NameNodeDataNodeNodeManagerHistoryServer
  • 若缺少 HistoryServer,请检查 spark-env.shSPARK_HISTORY_OPTS 配置及 HDFS 日志目录是否已创建。

slave1slave2 节点分别执行 jps,确认 NodeManager 已启动:

bash 复制代码
jps

预期输出(slave1 节点):

bash 复制代码
23456 ResourceManager
23457 NodeManager
23458 DataNode

预期输出(slave2 节点):

bash 复制代码
34567 NodeManager
34568 DataNode
12347 SecondaryNameNode

9.2 提交 SparkPi 任务验证两种模式

9.2.1 client 模式验证

master 节点执行:

bash 复制代码
spark-submit --class org.apache.spark.examples.SparkPi \
--master yarn \
--deploy-mode client \
/opt/module/sparkonyarn/examples/jars/spark-examples_2.12-3.0.3.jar 10

预期输出(关键部分):

bash 复制代码
Pi is roughly 3.141592653589793

✅ 若控制台能直接打印出 Pi is roughly ...,说明 client 模式提交成功,Driver 运行在客户端节点。

9.2.2 cluster 模式验证

master 节点执行:

bash 复制代码
spark-submit --class org.apache.spark.examples.SparkPi \
--master yarn \
--deploy-mode cluster \
/opt/module/sparkonyarn/examples/jars/spark-examples_2.12-3.0.3.jar 10

预期输出(关键部分):

bash 复制代码
20/09/17 07:50:01 INFO yarn.Client: Submitting application application_1699999999999_0001
20/09/17 07:50:02 INFO yarn.Client: Application report for application_1699999999999_0001 (state: ACCEPTED)
20/09/17 07:50:05 INFO yarn.Client: Application report for application_1699999999999_0001 (state: RUNNING)
20/09/17 07:50:08 INFO yarn.Client: Application report for application_1699999999999_0001 (state: FINISHED)

📌 cluster 模式下 Driver 运行在 YARN 容器内部,控制台不会 直接打印 Pi is roughly ...,需通过 YARN WebUI 或 Spark 历史服务器查看计算结果。

8.3 通过 YARN WebUI 查看任务状态和日志

  1. 浏览器访问 YARN WebUI:http://slave1:8088
  2. Active ApplicationsFinished Applications 列表中,找到刚提交的 SparkPi 任务;
  3. 点击任务 Application ID ,进入任务详情页,可查看:
    • 任务运行状态ACCEPTEDRUNNINGFINISHED
    • 日志入口 :点击 Logs 链接,查看 Driver 与 Executor 的 stdout/stderr 日志;
    • 资源使用情况:查看分配的 vCores、内存等指标。

💡 若任务已结束,也可通过 Spark 历史服务器 http://master:18080 查看已完成任务的执行详情与日志。

相关推荐
NailiConveyor1 小时前
智能物流装备市场的技术观察|输送设备应用与自动化渗透|仓储物流装备的数据分析
大数据·自动化·业界资讯
2601_960356382 小时前
2026届用户分析师校招能力栈:SQL、指标体系、BI与AI分析
大数据
YangYang9YangYan2 小时前
资金分析校招 JD 拆解,现金流建模与数据分析能力怎么准备
大数据·人工智能·数据分析
名不经传的养虾人2 小时前
从0到1:企业级AI项目迭代日记 Vol.110|协作有了预算,延迟有了归因,知识有了保真
大数据·人工智能·机器人·ai编程·企业ai
蓝速科技2 小时前
会议室门牌显示模板选型与品牌视觉适配落地指南丨蓝速科技
大数据·运维·数据库·人工智能·科技
LONGZETECH2 小时前
深入拆解无人机组装四大技术难关:焊接、接线、调参、转向校验
大数据·人工智能·系统架构·无人机
GlobalInfo3 小时前
机器人力控采集芯片全球市场深度分析:人形机器人分布式力感知下的24位Delta-Sigma与多通道同步博弈
大数据·人工智能·ai·机器人
智购科技自动贩卖机3 小时前
自动售货机嵌入式系统时钟同步与时间管理实战:从RTC校准到断网时间保持的工程实践
大数据·linux·数据库·人工智能·yolo
雨辰AI3 小时前
多租户数据库资源配额管控|避免租户资源抢占雪崩(金仓 / 达梦 / 高斯 /openGauss 全库原生适配)
java·大数据·数据库·后端