Flink 内存模型
- 大数据中所有开源的框架都会使用到JVM,不如,MapReduce,Storm,Spark等,这些计算框架处理数据过程中涉及到将大量数据存储到内存中,此时如果内存管理过渡依赖JVM,会出现java对象存储密度低导致内存使用率低以及垃圾回收导致的系统不稳定问题,这极大影响了系统的性能和稳定性。
- Flink也是计算框架,计算过程中同样也是基于JVM,但是Flink实现了内存管理,即脱离JVM堆内存进行管理,统一且有效的管理堆内存和堆外内存,确保大规模数据处理不会因为GC等问题造成系统不稳定。
Flink内存模型图解
-
Flink 1.10版本以后为了满足更细粒度以及灵活的内存管理,升级了内存模型,调整后内存模型如下图,而且Flink中计算主要存在于TaskManager节点,这里说的Flink内存模型也就是TaskManager的内存模型,JobManager的内存模型与TaskManager的内存模型类似
-
如上图,Flink总内存(Total Process Memory)包含了Flink总内存(Total Flink Memory) 和JVM特定内存,Flink总内存又包括JVM堆内存(JVM Heap),托管内存(Managed Momory),直接内存(Direct Memory),下面我们分别介绍每一部分的功能以及Flink提供的参数配置
Flink 总内存(Total Flink Memory)
- TaskManager 进程占用的所有与Flink相关的内存,不包括JVM特定内存部分,包含6个部分内存(Framework堆内存, Task堆内存,托管内存,Framework非堆内存,Task非堆内存, Network),关于Flink Framework 和Flink Task 使用的内存 既有堆内内存也有堆外内存,托管内存和Network使用的仅仅是堆外内存。
- Flink 总内存配置参数根据不同的部署场景不同:taskmanager.memory.flink.size 或者 taskmanager.memory.process.size(容器部署指定参数),无默认值,需要用户指定。
Flink 堆内存(JVM Heap)
- Flink 堆内存就是JVM堆内存(JVM Heap),分为Framework堆内存(Framework Heap)和Task堆内存(Task Heap),其中Framework主要用于Flink 框架本身需要的内存空间,Task 堆内存则用于Flink算子用户代码的执行,也被称为TaskExecutor使用的内存,两者主要区别用于是否将内存计入Slot计算资源中,Framework 内存不会将内存分配给Slot使用,Task 堆内存会分配给Slot。
Framework 堆内存(Framework Heap)
- Framework堆内存配置参数为:taskmanager.memory.framework.heap.size,该值默认为 128M。
Task 堆内存(Task Heap)
- Task堆内存配置参数为:taskmanager.memory.task.heap.size,该值没有默认值,如果没有指定会自动用Flink总内存 减去 Framework堆内存(Framework Heap),减去托管内存(Managed Memory),减去Framework 非堆内存(Framework Off-Heap),减去Task非堆内存(Task Off-Heap),减去 NetWork,剩下的内存就是Task堆内存。
Flink 非堆内存(Off-Heap Memory)
- 非堆内存也可以叫做堆外内存,更准去来说是大部分的堆外内存,包含了托管内存(Managed Memory),直接内存(Direct Memory)两部分
托管内存(Menaged Memory)
- 托管内存是Flink 负责分配和管理的本地堆外内存,在流处理作业中用于RocksDBstateBackend状态存储后段,在批处理作业中用于排序,哈希表,缓存中间结果。
- 托管内存(Menaged Memory)配置参数油如下两个:
- taskmanager.memory.managed.fraction,默认值0.4,如果未显式指定托管内存大小,则使用 总Flink内存的百分比作为托管内存。
- taskmanager.memory.managed.size,无默认值,一般也不指定,而是按照比例来推定,更加灵活。
直接内存(Direct Memory)
- 直接内存 分为 Framework 非堆内存(Framework Off-Heap),Task 非堆内存(Task Off-Heap) 和Network 三部分,直接内存主要作用是减少GC压力,提升性能效率。
- Framework 非堆内存(Framework Off-Heap)
- Framework 非堆内存即waskexxecutor的Framework堆外内存大小,不会分配给slot,配置参数为:taskmanager.memory.framework.off-heap.size,默认值128M。
- Task 非堆内存(Task Off-Heap)
- Task 非堆内存,配置参数taskmanager.memory.task.off-heap.size,默认值为0,即不使用。
- Network
- Network内存存储空间主要用于 给予Netty进行网络数据交换数据传输的本地缓存,例如:TaskManager之间Shuffle,广播,与外部组件的数据传输。Network的配置相关参数有3个,分别如下:
- taskmanager.memory.network.min:网络缓存的最小值,默认64MB;
- taskmanager.memory.network.max:网络缓存的最大值,默认1GB;
- taskmanager.memory.network.fraction: 网络混存占flink总内存manager.memory.flink.size的比例,默认值0.1,如果根据比例算出的内存量比最小值小或者比最大值大,就会限制到最小值或者最大值。
JVM特定内存
-
JVM特定内存是JVM堆外内存的另一小部分内存,其不再Flink总内存范围之内,包括jvm元空间(JVM Metaspace) 和JVm Overhead两部分,其中JVM元空间存储JVM加载类的元数据,加载的类越多,需要的内存空间越大,JVM Overhead 则主要用于其他JVM开销,例如代码缓存,线程栈等。
-
Flink 中将内存分成不同的区域,实现了更加精准的内存控制,在使用Flink过程中一般指定Flink总内存(Total Flink Memory,taskmanager.memory.flink.size)即可,其他额外指定JVM内存参数不需额外指定,如果需要根据Flink程序做一些调整建议有限调整fraction 比例参数,例如:网络缓存占比taskmanager.memory.network.fraction(根据网络流量大小调节)与托管内存占比
-
taskmanager.memory.managed.fraction(根据RocksDB状态大小调节),这样做可以间接影响任务内存的配额,需要特别注意的是如果手动指定较多的固定参数哼可能出现内存配额冲突导致的Flink程序部署失败。