摸鱼大数据——Spark基础——Spark On Yarn环境配置和部署

摸鱼大数据——Spark基础——Spark On Yarn环境配置和部署

一、背景与问题

在大数据处理场景中,Spark On Yarn 是最常见的运行模式之一。其核心价值在于借助 YARN(Yet Another Resource Negotiator)的资源调度能力,实现 Spark 作业的弹性扩展和资源隔离。然而,实际部署中常遇到以下问题:

  1. 资源分配不均:未合理配置内存和核心数导致任务失败
  2. 版本兼容性:Spark 与 Hadoop 版本不匹配引发的异常
  3. 性能瓶颈:未优化数据分区导致的计算效率低下
  4. 安全风险:未配置权限控制导致的数据泄露

本文将深入解析 Spark On Yarn 的底层机制,结合真实开发场景,提供可落地的配置方案。

二、基本原理

1. YARN 架构原理

YARN 采用主从架构,核心组件包括:

  • ResourceManager(RM):全局资源协调者
  • NodeManager(NM):节点资源管理器
  • ApplicationMaster(AM):应用协调器(Spark 通过 AM 管理作业)

YARN 的资源调度流程如下:

  1. ApplicationMaster 向 RM 申请资源
  2. RM 分配资源并启动 Container
  3. NM 启动 Container 执行任务
  4. 任务完成后向 AM 汇总结果

2. Spark On YARN 工作流程

Spark On YARN 的关键区别在于:

传统 Spark StandaloneSpark On YARN
自建集群管理借用 Hadoop 集群资源
需要单独部署集群可直接使用 Hadoop 集群
资源隔离能力弱支持细粒度资源调度
集群管理成本高资源利用率高

Spark 作业运行时,Driver 作为 ApplicationMaster 在 YARN 上注册,Executor 作为 Container 运行。

三、环境准备

1. 系统要求

建议使用 CentOS 7+ 系统,安装以下组件:

# 安装 Java 1.8
sudo yum install -y java-1.8.0-openjdk

# 安装 Hadoop 3.3.6
wget https://archive.apache.org/dist/hadoop/core/hadoop-3.3.6/hadoop-3.3.6.tar.gz
tar -zxvf hadoop-3.3.6.tar.gz -C /usr/local
ln -s /usr/local/hadoop-3.3.6 /usr/local/hadoop

# 配置环境变量
export JAVA_HOME=/usr/lib/jvm/java-1.8.0-openjdk
export HADOOP_HOME=/usr/local/hadoop
export PATH=$JAVA_HOME/bin:$HADOOP_HOME/bin:$PATH

2. Spark 安装

下载 Spark 3.3.2(需与 Hadoop 版本匹配):

wget https://archive.apache.org/dist/spark/spark-3.3.2/spark-3.3.2-bin-hadoop3.3.tgz
tar -zxvf spark-3.3.2-bin-hadoop3.3.tgz -C /usr/local
ln -s /usr/local/spark-3.3.2-bin-hadoop3.3 /usr/local/spark

四、核心实现

1. Spark On YARN 配置

关键配置文件 /usr/local/spark/conf/spark-defaults.conf:

# Spark 集群模式
spark.master                     yarn

# 最大Executor内存(注意:需小于YARN可用内存)
spark.executor.memory           4g

# Executor核心数
spark.executor.cores            2

# 驱动内存
spark.driver.memory             2g

# 本地存储路径
spark.local.dir                 /tmp/spark-local

# 是否启用动态资源分配
spark.dynamicAllocation.enabled true

# 最小/最大Executor数
spark.dynamicAllocation.minExecutors 1
spark.dynamicAllocation.maxExecutors 10

2. 提交作业命令

# 提交Spark作业到YARN
spark-submit \
  --master yarn \
  --deploy-mode cluster \
  --class com.example.WordCount \
  --conf spark.executor.memory=4g \
  --conf spark.executor.cores=2 \
  --driver-memory 2g \
  /path/to/your.jar \
  hdfs://namenode/path/input \
  hdfs://namenode/path/output

3. 资源分配优化

// SparkConf 配置示例
val conf = new SparkConf(true)
  .set("spark.yarn.driverMemory", "2g")
  .set("spark.yarn.executorMemory", "4g")
  .set("spark.executor.cores", "2")
  .set("spark.dynamicAllocation.maxExecutors", "10")

五、完整案例

1. 案例描述

处理日志文件统计访问量,要求:

  • 读取HDFS日志文件
  • 按IP地址统计访问次数
  • 输出到HDFS

2. 完整代码示例

// WordCount.scala
object WordCount {
  def main(args: Array[String]): Unit = {
    val conf = new SparkConf(true)
      .set("spark.master", "yarn")
      .set("spark.driver.memory", "2g")
      .set("spark.executor.memory", "4g")
      .set("spark.executor.cores", "2")
      .set("spark.dynamicAllocation.enabled", "true")
      .set("spark.dynamicAllocation.maxExecutors", "10")
    
    val sc = new SparkContext(conf)
    
    val logRDD = sc.textFile("hdfs://namenode/path/to/logs.txt")
    
    val wordCount = logRDD
      .flatMap(line => line.split("\\s+"))
      .map(word => (word, 1))
      .reduceByKey(_ + _)
    
    wordCount.saveAsTextFile("hdfs://namenode/path/output")
    sc.stop()
  }
}

3. 运行流程

  1. 提交作业:spark-submit --class WordCount ...
  2. YARN 申请资源
  3. 启动Driver和Executor
  4. 执行计算任务
  5. 保存结果

六、源码解析

1. SparkContext 初始化

// SparkContext.scala 源码片段
def initializeContext(): Unit = {
  if (conf.get("spark.master").startsWith("yarn")) {
    // 初始化YARN模式
    yarnConf = new YarnConfiguration(conf)
    yarnConf.set("spark.yarn.driverMemory", "2g")
    yarnConf.set("spark.yarn.executorMemory", "4g")
    yarnConf.set("spark.yarn.executorCores", "2")
    yarnConf.set("spark.dynamicAllocation.maxExecutors", "10")
  }
}

关键点:

  • spark.yarn.driverMemory 设置Driver内存
  • spark.yarn.executorMemory 设置Executor内存
  • spark.yarn.executorCores 设置Executor核心数
  • 动态资源分配配置

2. TaskScheduler 初始化

// TaskSchedulerImpl.scala 源码片段
def start(): Unit = {
  if (conf.get("spark.master").startsWith("yarn")) {
    // 初始化YARN TaskScheduler
    val yarnScheduler = new YarnScheduler(this, conf)
    yarnScheduler.start()
  }
}

七、进阶使用

1. 动态资源分配优化

# 启用动态资源分配
spark.dynamicAllocation.enabled=true
spark.dynamicAllocation.maxExecutors=10
spark.dynamicAllocation.minExecutors=1
spark.dynamicAllocation.executorAllocationRatio=1.5

2. 内存调优策略

// 内存分配策略配置
spark.executor.memoryOverhead=2g
spark.driver.memoryOverhead=1g
spark.memory.fraction=0.6
spark.memory.storageFraction=0.5

3. 资源隔离策略

# 配置YARN资源隔离
spark.yarn.scheduler.vcorePerExecutor=2
spark.yarn.scheduler.memoryPerExecutor=4g

八、性能与工程实践

1. 性能优化策略

优化项说明
分区策略采用 repartition 或 coalesce 调整分区数
缓存策略对中间结果使用 cache() 或 persist()
数据倾斜使用 salting 策略处理热点Key
网络传输启用 spark.shuffle.service.enabled=true

2. 安全风险防范

  • 启用 Hadoop Kerberos 认证:

    # 配置kerberos
    spark.kerberos.principal=spark/_hostname@REALM
    spark.kerberos.keytab=/path/to/keytab
  • YARN 权限控制:

    # 配置YARN ACL
    yarn.acl_admins=spark_user
    yarn.acl_admins=mapreduce_user

3. 异常处理机制

// 异常处理示例
try {
  val result = spark.sql("SELECT * FROM logs")
  result.show()
} catch {
  case e: Exception =>
    logger.error("作业执行异常", e)
    System.exit(1)
}

九、常见问题与踩坑

1. 常见错误及解决办法

错误信息原因解决方案
Driver lostDriver 内存不足增加 spark.driver.memory
Executor lostExecutor 内存不足增加 spark.executor.memory
Too many open files文件句柄不足调整 spark.executor.memoryOverhead
ClassNotFoundException类路径缺失检查 spark.driver.extraClassPath

2. 版本兼容性问题

组合问题解决方案
Spark 3.3.2 + Hadoop 3.3依赖冲突确保版本匹配
Spark 3.3.2 + Hadoop 3.2配置不兼容使用 spark.hadoop.yarn.resourcemanager.address

3. 资源分配陷阱

# 错误配置示例
spark.executor.memory=4g  # 导致资源不足
spark.executor.cores=2    # 导致CPU资源浪费

十、最佳实践

1. 推荐配置方案

# 推荐配置参数
spark.master=yarn
spark.executor.memory=4g
spark.executor.cores=2
spark.driver.memory=2g
spark.dynamicAllocation.enabled=true
spark.dynamicAllocation.maxExecutors=10
spark.dynamicAllocation.minExecutors=1
spark.dynamicAllocation.executorAllocationRatio=1.5
spark.memory.fraction=0.6
spark.memory.storageFraction=0.5

2. 集群资源规划建议

集群规模推荐配置
小型集群(10节点)每节点4GB内存,2核CPU
中型集群(50节点)每节点16GB内存,4核CPU
大型集群(100+节点)每节点32GB内存,8核CPU

3. 安全配置建议

  • 启用 Kerberos 认证
  • 配置 YARN ACL 权限
  • 使用加密传输(SSL/TLS)
  • 配置审计日志

十一、总结

Spark On Yarn 是大数据处理的首选模式,其核心优势在于:

  • 灵活的资源调度能力
  • 与 Hadoop 集群的深度集成
  • 简化集群管理流程

但需要注意:

  • 避免在小规模测试环境使用(资源浪费)
  • 需要严格配置资源参数
  • 需要关注安全配置

在实际项目中,建议:

  • 对复杂计算使用动态资源分配
  • 对数据倾斜使用 salting 策略
  • 对内存敏感任务进行精细调优
  • 对安全要求高的场景启用 Kerberos 认证

通过合理配置和优化,Spark On Yarn 可以实现高效的分布式计算,是现代大数据处理的基石。

最后修改于:2026年09月21日 01:03

评论已关闭

推荐阅读

AIGC实战——Transformer模型
2024年12月01日
Socket TCP 和 UDP 编程基础(Python)
2024年11月30日
python , tcp , udp
如何使用 ChatGPT 进行学术润色?你需要这些指令
2024年12月01日
AI
最新 Python 调用 OpenAi 详细教程实现问答、图像合成、图像理解、语音合成、语音识别(详细教程)
2024年11月24日
ChatGPT 和 DALL·E 2 配合生成故事绘本
2024年12月01日
omegaconf,一个超强的 Python 库!
2024年11月24日
【视觉AIGC识别】误差特征、人脸伪造检测、其他类型假图检测
2024年12月01日
[超级详细]如何在深度学习训练模型过程中使用 GPU 加速
2024年11月29日
Python 物理引擎pymunk最完整教程
2024年11月27日
MediaPipe 人体姿态与手指关键点检测教程
2024年11月27日
深入了解 Taipy:Python 打造 Web 应用的全面教程
2024年11月26日
基于Transformer的时间序列预测模型
2024年11月25日
Python在金融大数据分析中的AI应用(股价分析、量化交易)实战
2024年11月25日
AIGC Gradio系列学习教程之Components
2024年12月01日
Python3 `asyncio` — 异步 I/O,事件循环和并发工具
2024年11月30日
llama-factory SFT系列教程:大模型在自定义数据集 LoRA 训练与部署
2024年12月01日
Python 多线程和多进程用法
2024年11月24日
Python socket详解,全网最全教程
2024年11月27日
python之plot()和subplot()画图
2024年11月26日
理解 DALL·E 2、Stable Diffusion 和 Midjourney 工作原理
2024年12月01日