Spark on YARN集群部署实战指南

一、YARN资源调度集成原理
1.1 架构交互模型
sequenceDiagram
participant SparkSubmit
participant YARN_RM
participant YARN_NM
participant HDFS
SparkSubmit->>YARN_RM: 提交应用
YARN_RM->>YARN_NM: 分配容器
YARN_NM->>HDFS: 下载依赖
YARN_NM->>YARN_RM: 注册Executor
SparkSubmit->>YARN_NM: 执行任务
YARN_NM->>YARN_RM: 状态更新
1.2 部署模式对比
| 模式 | Cluster Mode | Client Mode |
|---|
| Driver位置 | YARN集群 | 提交客户端 |
| 适用场景 | 生产环境 | 开发调试 |
| 日志访问 | 需通过YARN查看 | 直接输出到客户端 |
| 资源释放 | 自动回收 | 需手动终止 |
二、集群环境配置
2.1 环境变量配置
export HADOOP_CONF_DIR=$HADOOP_HOME/etc/hadoop
export YARN_CONF_DIR=$HADOOP_HOME/etc/hadoop
export SPARK_EXECUTOR_MEMORY=4g
export SPARK_DRIVER_MEMORY=2g
2.2 核心配置参数
spark.master yarn
spark.yarn.archive hdfs:///spark/jars/spark-yarn-archive.zip
spark.yarn.jars hdfs:///spark/jars/*
spark.driver.cores 1
spark.executor.instances 5
三、任务提交与监控实战
3.1 Python任务提交示例
from pyspark.sql import SparkSession
spark = SparkSession.builder \
.appName("YARN WordCount") \
.config("spark.executor.memory", "4g") \
.config("spark.dynamicAllocation.enabled", "true") \
.getOrCreate()
text_file = spark.sparkContext.textFile("hdfs:///input/data.txt")
counts = text_file.flatMap(lambda line: line.split()) \
.map(lambda word: (word, 1)) \
.reduceByKey(lambda a, b: a + b)
counts.saveAsTextFile("hdfs:///output/wordcount")
3.2 任务提交命令
spark-submit \
--master yarn \
--deploy-mode cluster \
--executor-memory 4G \
--num-executors 10 \
--conf spark.dynamicAllocation.maxExecutors=20 \
hdfs:///apps/wordcount.py
3.3 任务状态监控
flowchart TD
A[提交任务] --> B[获取ApplicationID]
B --> C[YARN Web UI监控]
C --> D{运行成功?}
D -->|是| E[查看输出结果]
D -->|否| F[查看日志排查]
四、动态资源分配策略
4.1 动态调整算法
executors_{target} = \max(\lceil\frac{pendingTasks}{tasksPerExecutor}\rceil, executors_{min})
4.2 配置参数说明
| 参数 | 默认值 | 说明 |
|---|
| spark.dynamicAllocation.enabled | false | 启用动态分配 |
| spark.dynamicAllocation.minExecutors | 0 | 最小Executor数 |
| spark.dynamicAllocation.maxExecutors | ∞ | 最大Executor数 |
| spark.dynamicAllocation.initialExecutors | minExecutors | 初始Executor数 |
4.3 配置示例
spark = SparkSession.builder \
.config("spark.dynamicAllocation.enabled", "true") \
.config("spark.dynamicAllocation.minExecutors", "2") \
.config("spark.dynamicAllocation.maxExecutors", "20") \
.config("spark.shuffle.service.enabled", "true") \
.getOrCreate()
五、日志管理与问题排查
5.1 日志访问方法
yarn logs -applicationId application_123456789_0001
hdfs dfs -cat /tmp/logs/root/logs/application_123456789_0001/*
5.2 日志聚合配置
<property>
<name>yarn.log-aggregation-enable</name>
<value>true</value>
</property>
<property>
<name>yarn.log.server.url</name>
<value>http://logserver:19888/jobhistory/logs</value>
</property>
5.3 常见错误排查表
| 错误信息 | 原因分析 | 解决方案 |
|---|
| ApplicationMaster退出代码: 10 | 内存不足 | 增加spark.executor.memory |
| Container运行失败 | 依赖缺失 | 检查spark.yarn.archive配置 |
| Executor失去联系 | 网络分区 | 检查YARN节点状态 |
| 任务卡在ACCEPTED状态 | 资源不足 | 增加集群资源或调整调度策略 |
六、性能优化实践
6.1 资源配比公式
Executor内存 = spark.executor.memoryOverhead + spark.executor.memory
推荐配比:\frac{内存}{核数} \geq 4GB
6.2 优化参数示例
.config("spark.executor.cores", "4") \
.config("spark.executor.memory", "8g") \
.config("spark.executor.memoryOverhead", "2g") \
.config("spark.sql.shuffle.partitions", "200") \
七、监控指标采集
7.1 Prometheus监控配置
.config("spark.metrics.conf.*.sink.prometheus.class", "org.apache.spark.metrics.sink.PrometheusSink") \
.config("spark.metrics.conf.*.sink.prometheus.port", "9090") \
7.2 关键监控指标
| 指标名称 | 说明 |
|---|
| spark_driver_ExecutorTasks | 执行中任务数 |
| spark_executor_filesystem_hdfs_read_rates | HDFS读取速率 |
| spark_job_activeJobs | 活跃作业数 |
生产建议:建议结合Kerberos进行安全认证,定期清理HDFS上的事件日志。完整配置模板可参考GitHub仓库
附录:常用YARN命令速查
| 功能 | 命令 |
|---|
| 终止应用 | yarn application -kill |
| 查看队列资源 | yarn queue -status default |
| 查看节点状态 | yarn node -list -all |
| 资源调度器配置 | yarn scheduler -conf |