Flink内存管理庞大而复杂,其究竟划分为哪些结构,又是为什么这么划分,Flink版本迭代过程中内存模型又有何变化,这都是需要关注的问题,本文结合Flink源码与官方文档总结了Flink内存管理的重点内容。有问题的地方,还请批评指正~
文章目录
一. Flink1.10及以上版本内存管理
1.1 TaskManager内存组成与配置
组成部分 | 配置参数 | 作用 | 补充说明 |
---|---|---|---|
Framework Heap Memory | taskmanager.memory.framework.heap.size | Flink 框架的 JVM 堆内存 | 进阶配置 |
Task Heap | taskmanager.memory.task.heap.size | Flink 应用的算子及用户代码 的 JVM 堆内存 | |
Managed memory | taskmanager.memory.managed.size taskmanager.memory.managed.fraction | 用于排序、哈希表、缓存中间结果 及RocksDB State Backend 的本地内存 | 由 Flink 管理 |
Framework Off-heap | taskmanager.memory.framework.off-heap.size | Flink 框架的堆外内存 | 进阶配置 |
Task Off-Heap | taskmanager.memory.task.off-heap | Flink 应用的算子及用户代码的堆外内存 | |
Network | taskmanager.memory.network.min taskmanager.memory.network.max taskmanager.memory.network.fraction | 任务之间数据传输 的直接内存(例如网络传输缓冲) | 该内存部分为基于 Flink 总内存的受限的等比内存部分。 |
JVM Metaspace | taskmanager.memory.jvm-metaspace.size | Flink JVM 进程的 Metaspace。 | |
JVM overhead | taskmanager.memory.jvm-overhead.min taskmanager.memory.jvm-overhead.max taskmanager.memory.jvm-overhead.fraction | 其他 JVM 开销的本地内存,例如栈空间、垃圾回收空间等。 | 该内存部分为基于进程总内存的受限的等比内存部分。 |
1.2 JobManager内存组成与配置
组成部分 | 配置参数 | 作用 |
---|---|---|
JVM 堆内存 | jobmanager.memory.heap.size | JobManager 的 JVM 堆内存。 所需大小取决于 运行作业数量 、作业结构 及用户代码需求 (作业提交及checkpoint完成回调函数中执行的用户代码) |
堆外内存 | jobmanager.memory.off-heap.size | Flink框架依赖(例如Akka)及作业提交及checkpoint完成回调函数中执行的用户代码可能用到堆外内存 |
JVM Metaspace | jobmanager.memory.jvm-metaspace.size | 同TaskManager |
JVM overhead | jobmanager.memory.jvm-overhead.min jobmanager.memory.jvm-overhead.max jobmanager.memory.jvm-overhead.fraction | 同TaskManager |
1.3 内存管理源码解析
从源码看内存结构
Flink memory
public class TaskExecutorFlinkMemory implements FlinkMemory {
private final MemorySize frameworkHeap;
private final MemorySize frameworkOffHeap;
private final MemorySize taskHeap;
private final MemorySize taskOffHeap;
private final MemorySize network;
private final MemorySize managed;
.......
}
public class JobManagerFlinkMemory implements FlinkMemory {
private final MemorySize jvmHeap;
private final MemorySize offHeapMemory;
.......
}
Flink JVM memory
public class CommonProcessMemorySpec<FM extends FlinkMemory> implements ProcessMemorySpec {
private final FM flinkMemory;
private final JvmMetaspaceAndOverhead jvmMetaspaceAndOverhead;
.......
}
所有代码路径 org.apache.flink.runtime.util.config.memory
二. Flink1.9及以下版本内存管理
- MemoryManager
MemoryManager中有MemoryPool,管理着众多MemorySegment。
MemoryPool有两个子类:HybridHeapMemoryPool, HybridOffHeapMemoryPool包含了内存分配allocate方法。
MemorySegment
是一段固定长度的内存(默认32KB),也是Flink最小内存分配单元,并且提供了非常高效的读写方法(Java的unsafe(不会被JVM管理,需要手动回收))。底层内存可以是申请的堆外内存ByteBuffer,也可以是堆内普通Java byte[]数组。MemorySegment在TaskManager启动时分配一次,在TaskManager关闭时销毁,内存是复用的,不会被垃圾回收器回收。
- HeapMemorySegment 用于申请堆内内存
- HybridMemorySegment 用于申请(堆内)+ 堆外内存,其中是否申请堆内由OffHeapBuffer是否为null决定,这样做是为了优化性能,堆内外内存都需要时,减少类加载。
- NetworkBuffer是MemorySegmentProvider的一个实现类
MemorySegmentProvider用来申请和释放memory segment资源
/**
* The provider used for requesting and releasing batch of memory segments.
*/
public interface MemorySegmentProvider {
Collection<MemorySegment> requestMemorySegments() throws IOException;
void recycleMemorySegments(Collection<MemorySegment> segments) throws IOException;
}