系列文章目录
目录
前言
如果大数据从业者经常使用Spark,Flink两大计算引擎,内存管理模型概念是使用者必须要知道的概念,熟悉内存管理模型可以帮助大家写出更好的代码,计算性能较慢时可以根据内存管理模型重新分配或者优化资源。今天给大家讲解下基于Flink1.12版本的内存管理模型,以及引申出Flink对堆外内存的使用。以后有时间的话还会出一期Spark的内存模型做比较和源代码走读,大家先关注不迷路~
一、JobManager内存
引用官网的一直图:
这是Flink1.12版本的JobManager内存模型架构图,该的内存配置方法适用于 1.10 及以上版本的 TaskManager 进程和 1.11 及以上版本的 JobManager 进程,如果想了解之前版本的变动,可以参考官网的升级指南
可以看到JobManager的内存模型很简单了,主要是堆内存,堆外内存,JVM Metaspace和JVM Overhead组成。
- 堆内存:在作业提交时(例如一些特殊的批处理 Source)及 Checkpoint 完成的回调函数中执行的用户代码。
- 堆外内存:Flink 框架依赖(例如 Akka 的网络通信)或者 在作业提交时(例如一些特殊的批处理 Source)及 Checkpoint 完成的回调函数中执行的用户代码。
二、Flink Process Memory
Flink JVM 进程的*进程总内存(Total Process Memory)*包含了由 Flink 应用使用的内存(Flink 总内存)以及由运行 Flink 的 JVM 使用的内存。 Flink 总内存(Total Flink Memory)包括 JVM 堆内存(Heap Memory)和堆外内存(Off-Heap Memory)。 其中堆外内存包括直接内存(Direct Memory)和本地内存(Native Memory)。
配置 Flink 进程内存最简单的方法是指定以下两个配置项中的任意一个:
配置项 | TaskManager 配置参数 | JobManager 配置参数 |
---|---|---|
Flink 总内存 | taskmanager.memory.flink.size | jobmanager.memory.flink.size |
进程总内存 | taskmanager.memory.process.size | jobmanager.memory.process.size |
另外不建议同时设置进程总内存和 Flink 总内存。 这可能会造成内存配置冲突,从而导致部署失败。 额外配置其他内存部分时,同样需要注意可能产生的配置冲突。
三. TaskManager内存
- Framework Heap: 用于 Flink 框架的 JVM 堆内存(进阶配置)。
- Task Heap: 用于 Flink 应用的算子及用户代码的 JVM 堆内存。
- Managed Memory:由 Flink 管理的用于排序、哈希表、缓存中间结果及 RocksDB State Backend 的本地内存。
- Framework Off-Heap: 用于 Flink 框架的堆外内存(直接内存或本地内存)(进阶配置)。
- Task Off-Heap: 用于 Flink 应用的算子及用户代码的堆外内存。
- Network:用于任务之间数据传输的直接内存(例如网络传输缓冲)。
- JVM Metaspace: Flink JVM 进程的 Metaspace。
- JVM Overhead: 用于其他 JVM 开销的本地内存,例如栈空间、垃圾回收空间等。
四. 堆内存和堆外内存区别
如果有在使用Flink引起和Spark引擎的同学肯定会发现,两个框架同时规划了堆内存和堆外内存的划分。那这两种内存划分到底有什么有缺点呢?
首先这里所说的堆外堆内完全是基于JVM来说的,其中堆外内存是引用JDK的Unsafe类是实现,可以从类名看出,引用堆外内存是不安全不可控的,但是其优点也很明显,可以完全脱离JVM,直接操作内存。减少了不必要的内存开销,以及频繁的GC扫描和回收,提升了处理性能。堆外内存可以被精确地申请和释放,而且序列化的数据占用的空间可以被精确计算,所以相比堆内内存来说降低了管理的难度,也降低了误差。结合上图的TaskManager的内存模型看一下,使用堆外内存的用处大多在Managed Memory,Network这些对处理性能要求很高的地方。
总结
Flink内存模型是学习Flink技术必须要知道的概念,这里给大家讲解了JobManager和TaskManager的内存模型,通常被问的最多的也是TaskManager,希望大家抽点时间认真了解下。
欢迎大家扫一扫下面个人微信,我会拉大家进入大数据技术交流群,一起学习一起进步吧。