spark内存管理这一篇就够了

1. 堆内和堆外内存规划

1.1 堆内内存

堆内内存的大小,由 Spark 应用程序启动时的 –executor-memory 或 spark.executor.memory 参数配置。Executor 内运行的并发任务共享 JVM 堆内内存,这些任务在缓存 RDD 数据和广播(Broadcast)数据时占用的内存被规划为存储(Storage)内存,而这些任务在执行 Shuffle 时占用的内存被规划为执行(Execution)内存,剩余的部分不作特殊规划,那些 Spark 内部的对象实例,或者用户定义的 Spark 应用程序中的对象实例,均占用剩余的空间。不一样的管理模式下,这三部分占用的空间大小各不相同。缓存

1.2 堆外内存

在默认状况下堆外内存并不启用,可经过配置 spark.memory.offHeap.enabled 参数启用,并由 spark.memory.offHeap.size 参数设定堆外空间的大小。除了没有 other 空间,堆外内存与堆内内存的划分方式相同,全部运行中的并发任务共享存储内存和执行内存。并发

2 . 内存空间分配

2.1 统一内存管理

Spark 1.6 以后引入的统一内存管理机制,与静态内存管理的区别在于存储内存和执行内存共享同一块空间,能够动态占用对方的空闲区域,如图 4 和图 5 所示性能

图 4 . 统一内存管理图示——堆内优化

spark.memory.fraction       堆内的存储内存和执行内存总共所占的比例,默认0.6spa

spark.storage.storageFraction     用于缓存数据的内存比例,默认0.5对象

图 5 . 统一内存管理图示——堆外blog

spark.memory.storageFraction         Storage内存所占堆外内存的比例,默认为0.5内存

其中最重要的优化在于动态占用机制,其规则以下:资源

  • 设定基本的存储内存和执行内存区域(spark.storage.storageFraction 参数),该设定肯定了双方各自拥有的空间的范围
  • 双方的空间都不足时,则存储到硬盘;若己方空间不足而对方空余时,可借用对方的空间;(存储空间不足是指不足以放下一个完整的 Block)
  • 执行内存的空间被对方占用后,可以让对方将占用的部分转存到硬盘,而后"归还"借用的空间(执行内存的强势)
  • 存储内存的空间被对方占用后,没法让对方"归还",由于须要考虑 Shuffle 过程当中的不少因素,实现起来较为复杂

图 6 . 动态占用机制图示开发

凭借统一内存管理机制,Spark 在必定程度上提升了堆内和堆外内存资源的利用率,下降了开发者维护 Spark 内存的难度,但并不意味着开发者能够高枕无忧。譬如,因此若是存储内存的空间太大或者说缓存的数据过多,反而会致使频繁的全量垃圾回收,下降任务执行时的性能,由于缓存的 RDD 数据一般都是长期驻留内存的 。因此要想充分发挥 Spark 的性能,须要开发者进一步了解存储内存和执行内存各自的管理方式和实现原理。