如果觉得这篇文章对您有帮助,别忘了点赞、分享或关注哦!您的一点小小支持,不仅能帮助更多人找到有价值的内容,还能鼓励我持续分享更多精彩的技术文章。感谢您的支持,让我们一起在技术的世界中不断进步!
Spark 堆内内存和堆外内存
1. 堆内内存(Heap Memory): Executor JVM的堆内存
- a. Execution Memory: 用于执行分布式任务,如shuffle、Sort、join和Aggregate操作
- b. Storage Memory: 用于缓存数据,例如缓存的 RDD 或 DataFrame 等持久化数据。它也用于存储广播变量。
- c. User Memory: 用于存储用户自定义数据结构
- d. Reserved Memory: 用于存储Spark内部对象,如存储系统中的BlockManager、DiskBlockManager等
2. 堆外内存(Off-Heap Memory: 通过Java Unsafe API,直接从操作系统中申请和释放内存空间
- a. Execution Memory(堆外)
- b. Storage Memory(堆外)
/etc/opt/spark-2.1.0-bin-hadoop2.6/bin/spark-submit \
--class com.datacrafter.WordCount \ # 运行的主类
--master yarn \ # 指定 Spark 集群的资源管理器为 YARN
--deploy-mode client \ # 以客户端模式提交任务,即 Driver 进程在提交任务的机器上运行
--driver-memory 4g \ # 为 Driver 进程分配 4GB 内存
--executor-memory 8g \ # 为每个 Executor 分配 8GB 内存
--num-executors 10 \ # 启动 10 个 Executor 进程
--executor-cores 4 \ # 每个 Executor 分配 4 个 CPU 核心
--conf spark.memory.fraction=0.8 \ # Spark 内存池中用于 Execution 和 Storage 的内存比例设置为 80%
--conf spark.memory.storageFraction=0.3 \ # Spark 内存池中用于 Storage 的内存比例设置为 30%
--queue ads \ # 将作业提交到 YARN 的 "ads" 队列
./WordCount.jar # 指定待提交的应用程序 JAR 包
Spark 内存管理机制
在Spark1.6之前,Spark采用的是静态管理(Static Memory
Manager)模式,Execution内存和Storage内存的分配占比全部是静态的,其值为系统预先设置的默认参数。
在Spark1.6后,为了考虑内存管理的动态灵活性,Spark的内存管理改为统一管理(Unified Memory
Manager)模式,支持Storage和Execution内存动态占用。至于静态管理方式任然被保留,可通过spark.memory.useLegacyMode参数启用。
1.静态内存管理(Static Memory Manager)
- 1.1 堆内内存分配
- 可用的存储内存 = systemMaxMemory * spark.storage.memoryFraction * spark.storage.safetyFraction
- 可用的执行内存 = systemMaxMemory * spark.shuffle.memoryFraction * spark.shuffle.safetyFraction
- systemMaxMemory其实就是通过参数–executor-memory 配置的
- 1.2 堆外内存分配
- 堆外内存默认情况下是不开启的,需要在配置中将spark.memory.offHeap.enabled设为True,同时配置spark.memory.offHeap.size参数设置堆大小。
- 堆外内存默认为384M,由系统参数spark.yarn.executor.memoryOverhead设定。
- 整体内存分为Storage和Execution两部分,由参数: spark.memory.storageFaction决定
2.统一内存管理(Unified Memory Manager)
- 2.1 堆内内存分配
- 堆内内存整体划分为Usable Memory(可用内存)和Reversed Memory(预留内存)两大部分
- 其中预留内存作为OOM等异常情况的内存使用区域,默认被分配300M的空间。
- 可用内存可进一步分为(Unified Memory)统一内存和Other内存其他两部分,默认比例6:4:
- 动态内存占用机制
- a.设置内存的初始值,即Execution和Storage均需设定各自的内存区域范围(默认参数0.5)
- b.若存在一方内存不足,另一方内存空余时,可占用对方内存空间
- c.双方内存均不足时,需落盘处理
- d.Execution内存被占用时,Storage需将此部分转存硬盘并归还空间
- e.Storage内存被占用时,Execution无需归还
- 可用的存储内存 = (systemMaxMemory -ReservedMemory) * spark.memoryFraction * spark.storage.storageFraction
- 可用的执行内存 = (systemMaxMemory -ReservedMemory) * spark.memoryFraction * (1-spark.storage.storageFraction)
- 2.2 堆外内存分配
- 和静态管理模式分配一致,堆外内存默认值为384M。
- 整体分为Storage和Execution两部分,且启用动态内存占用机制,其中默认的初始化占比值均为0.5。