概念备忘

内存分四块

  • Execution Memory:主要用于存放 Shuffle、Join、Sort、Aggregation 等计算过程中的临时数据
  • Storage Memory:主要用于存储 spark 的 cache 数据,例如RDD的缓存、unroll数据;
  • User Memory:主要用于存储 RDD 转换操作所需要的数据,例如 RDD 依赖等信息。
  • Reserved Memory(预留内存):系统预留内存,会用来存储Spark内部对象。

image.png

举例加深理解

使用 mapPartition 等,一个 Task 内部所有所有算子使用的数据空间的大小如果大于 User Mermory 的话,那么就会出现 OOM。

内存计算公式

  1. systemMemory = spark.executor.memory - Servivor = Runtime.getRuntime.maxMemory
  2. reservedMemory = 300MB
  3. usableMemory = systemMemory - reservedMemory
  4. StorageMemory= usableMemory * spark.memory.fraction * spark.memory.storageFraction
  5. ExecutorMemory = Eden + 2 * Survivor + Old
  6. Runtime.getRuntime.maxMemory = Eden + Survivor + Old
  7. WebUI显示的内存数是字节除以1000,会和真实有误差
  8. WEB_UI_StorageMemory = usableMemory * spark.memory.fraction = StorageExecutionMemory + ExecutionMemory
  9. #堆外申请多少就是多少,不存在JVM GC
  10. offHeapStorageMemory = spark.memory.offHeap.size = 10737418240

Task可申请内存量

Task共享堆内存,Task可申请内存 = Execution Memory * 1/2N ~ 1/N (N为当前运行Task数)
如果申请不在次范围,Task将被挂起。

其他

Executor 内运行的并发task共享 JVM 堆内内存。
storage 和 execution 内存都通过 MemoryManager 来申请和管理

不受 MemoryManager 管理,主要有两个作用:

  • 在 spark 运行过程中使用:比如序列化及反序列化使用的内存,各个对象、元数据、临时变量使用的内存,函数调用使用的堆栈等
  • 作为误差缓冲:由于 storage 和 execution 中有很多内存的使用是估算的,存在误差。当 storage 或 execution 内存使用超出其最大限制时,有这样一个安全的误差缓冲在可以大大减小 OOM 的概率

不受 MemoryManager 管理内存,由以下两部分组成:

  • 系统预留:大小默认为 RESERVED_SYSTEM_MEMORY_BYTES,即 300M,可以通过设置 spark.testing.reservedMemory 改变,一般只有测试的时候才会设置该配置,所以我们可以认为系统预留大小为 300M。另外,executor 的最小内存限制为系统预留内存的 1.5 倍,即 450M,若 executor 的总内存大小小于 450M,则会抛出异常
  • storage、execution 安全系数外的内存:大小为 (heap space - RESERVED_SYSTEM_MEMORY_BYTES)*(1 - spark.memory.fraction),默认为 (heap space - 300M)* 0.4

注意事项

Execution 被占用后,可让Storage将占用的部分转存到硬盘,然后归还借用的空间。反正则不行,Execution里存Shuffle数据无法归还。换种说法:当 Execution 空间不足而且 Storage 空间也不足的情况下,Storage 空间如果曾经使用了超过 Unified 默认的 50% 空间的话则超过部份会被强制 drop 掉一部份数据来解决 Execution 空间不足的问题 (注意:drop 后数据会不会丢失主要是看你在程序设置的 storage_level 来决定你是 Drop 到那里,可能 Drop 到磁盘上)
借用发生在堆内堆外内部,不会在彼此间互相借用。

参考资料

Apache Spark 统一内存管理模型详解  讲了很多不容易注意的细节
https://www.jianshu.com/p/999ef21dffe8
https://www.cnblogs.com/jcchoiling/p/6494652.html
https://www.cnblogs.com/qingyunzong/p/8955141.html#_label3
https://baijiahao.baidu.com/s?id=1617112541441372971&wfr=spider&for=pc
https://blog.csdn.net/qq_37303226/article/details/80774387

http://bourneli.github.io/scala/spark/2016/06/17/spark-unpersist-after-action.html
https://sparkbyexamples.com/spark/spark-persistence-storage-levels/