1. MemoryManager
Spark的内存主要分为管理储存(Storage)和执行(Execution),ExecutionMemory是指 Shuffles,joins,sorts和 aggregation 的操作;而StorageMemory 是缓存和广播数据相关的,每一个 JVM 会产生一个 MemoryManager 来负责管理内存。
MemoryManager 主要有几个功能:
•记录用了多少 StorageMemory 和ExecutionMemory
•申请 Storage、Execution 和Unroll Memory
•释放 Storage 和ExecutionMemory
其中MemoryManger有两个实现类,StaticMemoryManager和UnifiedMemoryManager。
图 1 MemoryManger类图2. StaticMemoryManager
今天我们先看看StaticMemoryManager,以下是ExecutionMemory,StorageMemory,UrollMemory在StaticMemoryManager的分配。
图 2 StaticMemoryManager内存管理图示——堆内对应的代码如下:
其中 systemMaxMemory 取决于当前 JVM 堆内内存的大小,最后可用的执行内存或者存储内存要在此基础上与各自的memoryFraction 参数和 safetyFraction 参数相乘得出。上述计算公式中的两个 safetyFraction 参数,其意义在于在逻辑上预留出1-safetyFraction 这么一块保险区域,降低因实际内存超出当前预设范围而导致 OOM 的风险(上文提到,对于非序列化对象的内存采样估算会产生误差)。值得注意的是,这个预留的保险区域仅仅是一种逻辑上的规划,在具体使用时 Spark 并没有区别对待,和"其它内存"一样交给了 JVM 去管理。
堆外的空间分配较为简单,只有存储内存和执行内存,如图 3 所示。可用的执行内存和存储内存占用的空间大小直接由参数 spark.memory.storageFraction 决定,由于堆外内存占用的空间可以被精确计算,所以无需再设定保险区域。
图 3 StaticMemoryManager内存管理图示——堆外对应的代码在MemoryManager.scala:
StaticMemoryManager申请StorageMemory见方法acquireStorageMemory
StaticMemoryManager申请ExecutionMemory见方法acquireExecutionMemory
StaticMemoryManager申请UnrollMemory见方法acquireUnrollMemory
MemoryManager 的具体实现上,Spark 1.6 之后默认为统一管理(Unified Memory Manager)方式,1.6 之前采用的静态管理(Static Memory Manager)方式仍被保留,可通过配置 spark.memory.useLegacyMode 参数启用。
网友评论