当前位置: 首页 > news >正文

关于spark在yarn上运行时候内存的介绍

在YARN上运行Spark时,内存管理是性能调优的核心环节。以下是 Driver MemoryExecutor Memory堆内存(Heap Memory)堆外内存(Off-Heap Memory) 的区别与配置方法,以及实际场景中的最佳实践:


1. 核心概念与区别

(1) Driver Memory
  • 角色:Driver是Spark应用程序的主控进程,负责:
    • 解析用户代码,生成DAG(任务执行计划)。
    • 调度Task到Executor,并监控执行状态。
    • 收集结果(如collect()操作)或广播变量。
  • 内存组成
    • 堆内存:存储元数据(如Task定义、广播变量)和收集的结果数据。
    • 堆外内存:JVM自身开销、直接内存(如网络传输缓存)。
  • 关键参数
    • spark.driver.memory:Driver的堆内存(默认1g)。
    • spark.driver.memoryOverhead:Driver的堆外内存(默认max(384MB, 0.1 * spark.driver.memory))。
(2) Executor Memory
  • 角色:Executor是工作节点上的任务执行进程,负责:
    • 执行具体的Task(如Map、Reduce操作)。
    • 缓存数据(如cache()persist())。
  • 内存组成
    • 堆内存:存储Task处理的数据、缓存的数据。
    • 堆外内存:Shuffle中间数据、原生操作(如HDFS读写缓存)。
  • 关键参数
    • spark.executor.memory:Executor的堆内存(默认1g)。
    • spark.executor.memoryOverhead:Executor的堆外内存(默认max(384MB, 0.1 * spark.executor.memory))。
    • spark.memory.fraction:Executor中用于计算和缓存的总内存占比(默认0.6)。
(3) 堆内存 vs 堆外内存
特性堆内存(Heap)堆外内存(Off-Heap)
管理方式由JVM垃圾回收器(GC)管理不受GC管理,需手动释放或依赖操作系统管理
存储内容Java对象实例(如RDD数据、集合)JVM元数据、直接缓冲区(DirectByteBuffer)、Shuffle临时文件
溢出风险OutOfMemoryError: Java heap spaceOutOfMemoryError: Direct buffer memory 或YARN/K8s容器被杀死
配置参数spark.driver.memoryspark.executor.memoryspark.driver.memoryOverheadspark.executor.memoryOverhead

2. 内存设置规则

(1) 总内存限制

在YARN集群中,Driver和Executor的内存需满足:

  • Driver总内存 ≤ YARN单容器内存上限(由yarn.scheduler.maximum-allocation-mb定义)。
  • Executor总内存 ≤ YARN单容器内存上限。

总内存计算公式:

Driver总内存 = spark.driver.memory + spark.driver.memoryOverhead
Executor总内存 = spark.executor.memory + spark.executor.memoryOverhead
(2) 配置建议
参数DriverExecutor说明
堆内存spark.driver.memoryspark.executor.memory- Driver:根据收集数据量和广播变量大小调整。
- Executor:根据分区数据量和缓存需求调整。
堆外内存spark.driver.memoryOverheadspark.executor.memoryOverhead- 默认值通常不足!若任务涉及大量Shuffle或Native操作,需手动增加。
内存分配比例-spark.memory.fraction调整Executor内计算内存(Execution)和缓存内存(Storage)的比例。
(3) 典型场景设置示例
  • 场景1:常规ETL任务

    spark-submit \
      --driver-memory 4g \
      --executor-memory 8g \
      --conf spark.executor.memoryOverhead=2g \
      --conf spark.driver.memoryOverhead=1g \
      ...
    
    • 说明:Executor处理数据分区,预留2GB堆外内存应对Shuffle。
  • 场景2:需collect()大量数据

    spark-submit \
      --driver-memory 16g \           # 收集10GB数据时,Driver堆内存需足够大
      --conf spark.driver.maxResultSize=10g \
      ...
    
    • 注意:避免collect(),优先使用分布式写入(如write.parquet())。
  • 场景3:机器学习(频繁Shuffle)

    spark-submit \
      --executor-memory 16g \
      --conf spark.executor.memoryOverhead=4g \  # Shuffle和原生库可能占用大量堆外内存
      --conf spark.memory.fraction=0.7 \         # 提高计算内存占比
      ...
    

3. 常见问题与调优

(1) Driver OOM(堆内存不足)
  • 表现java.lang.OutOfMemoryError: Java heap space
  • 解决方案
    • 增加spark.driver.memory
    • 避免在Driver中收集大数据(用take(n)替代collect())。
    • 减少广播变量大小。
(2) Executor OOM(堆内存不足)
  • 表现:Executor日志中抛出堆内存溢出。
  • 解决方案
    • 增加spark.executor.memory
    • 减少单个分区的数据量(通过repartition()增大分区数)。
    • 使用MEMORY_AND_DISK缓存级别。
(3) 容器被YARN杀死(堆外内存不足)
  • 表现:YARN日志提示 Container killed due to exceeding memory limits
  • 解决方案
    • 增大spark.executor.memoryOverheadspark.driver.memoryOverhead
    • 检查是否使用Native库(如OpenBLAS)导致堆外内存泄漏。
(4) Shuffle阶段频繁溢写磁盘
  • 表现:Spark UI中Shuffle Write/Read量过大,任务变慢。
  • 解决方案
    • 增大spark.executor.memoryspark.memory.fraction(为Execution内存留更多空间)。
    • 优化数据倾斜(加盐、拆分倾斜Key)。

4. 最佳实践总结

配置项推荐策略
Driver堆内存根据collect()数据量设置,通常为数据量的2倍,不超过YARN容器上限。
Executor堆内存根据分区数据量设置,建议8g~16g,避免单个Executor内存过大导致GC停顿。
堆外内存至少为堆内存的20%~30%(如spark.executor.memoryOverhead=4g当Executor堆内存为16g)。
Shuffle优化增大spark.sql.shuffle.partitions(默认200)到2-3倍数据分区数。
监控工具使用Spark UI + YARN Web UI + Prometheus监控堆/堆外内存趋势。

5. 完整示例配置

spark-submit \
  --master yarn \
  --deploy-mode cluster \
  --driver-memory 8g \
  --executor-memory 16g \
  --conf spark.driver.memoryOverhead=2g \
  --conf spark.executor.memoryOverhead=4g \
  --conf spark.memory.fraction=0.7 \
  --conf spark.sql.shuffle.partitions=2000 \
  --conf spark.serializer=org.apache.spark.serializer.KryoSerializer \
  --class com.example.Main \
  /path/to/your-app.jar

通过合理分配堆内外内存、监控资源使用,并结合业务逻辑优化,可以显著减少Spark作业的OOM风险和性能瓶颈。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.dtcms.com/a/95260.html

相关文章:

  • 计算机组成原理的学习day01
  • 【面试题】利用Promise实现Websocket阻塞式await wsRequest() 请求
  • 关于我对接了deepseek之后部署到本地将数据存储到mysql的过程
  • 卷积神经网络 - 微步卷积、空洞卷积
  • git 基本操作命令
  • Vue3 其它API readonly和shallowreadonly
  • 阿里云国际站代理商:如何通过并行文件系统提升IO性能?
  • CentOS 7 源码安装libjsoncpp-1.9.5库
  • vue3 vue-router 传递路由参数
  • Redis数据持久化机制 + Go语言读写Redis各种类型值
  • vue路由缓存问题
  • Linux MariaDB部署
  • Openssl自签证书相关知识
  • 技术改变生活的10种方式
  • 存储服务器是指什么
  • Java 8 代码重构实战之四 Lambda表达式重构工厂模式与责任链模式
  • JVM - 类加载相关
  • 做一个多级动态表单,可以保存数据和回显数据
  • 【论文分析】无人机轨迹规划,Fast-Planner:实时避障+全局最优的路径引导优化算法
  • Rust从入门到精通之进阶篇:12.高级类型系统
  • ubuntu虚拟机的磁盘扩容,虚拟机的克隆
  • 将ZABBIX结合AI实现自动化运维
  • <数据集>轨道异物识别数据集<目标检测>
  • 操作系统高频(四)linux基础
  • nginx-rtmp-module之ngx_rtmp_live_module.c代码详解
  • 前端显示no data(没有数据,一片空白)
  • ComfyUi教程之阿里的万象2.1视频模型
  • OGG故障指南:OGG-00446 Checkpoint table does not exist
  • 深度解析Spring Boot可执行JAR的构建与启动机制
  • Go 语言规范学习(2)