其实官方文档中的对于Flink内存模型讲解的已经很详细了,本文主要是介绍下个人对这个内存模型的理解,如果有理解不对的地方,希望大家帮忙指正下!因为接触Flink的时间比较晚,所以一上来我们使用的就是V1.10版本,TaskManager的内存模型与配置在该版本中做了很大的优化。

 

 

Flink 1.10之前的的内存模型存在的缺点:

    1. 流处理与批处理内存配置方法不同。比如Managed Memory这块内存,在批处理中有用,在流处理中使用不到的

    2. 内存配置细节繁多,概念比较难懂,比如容器化会有专用的cutoff内存

    3. RocksDB状态后端的内存不好配置(这部分个人没有理解,因为我们是使用的HDFS,没用RocksDB…)

    个人对V1.10版本之前的内存模型只是想有个简单的了解,不打算做深入的研究了,反正我们项目中后续使用的都是V1.10之后的版本...

 

 

Flink 1.10版本内存模型:

    Flink1.10版本内存模型架构如下图所示:

生产环境中flink内存优化 flink 1.10内存管理_内存模型

Total Process Memory对应Yarn/Mesos等容器化部署模式(需要用户指定),相当于申请容器的大小,Total Flink Memory对应standalone部署模式(需要用户指定)。

    Total Flink Memory内部分成了:堆内内存 + 堆外内存:

        堆内内存包括两部分:FreameWork Heap Memory(框架堆内存) + Task Heap Memory(任务堆内存)

        堆外内存包含三部分:Managed Memory(托管内存) + Framework Off-heap Memory(框架堆外内存) + Network Memory(网络内存)

 

官网已经总结的很详细了:

组成部分 

配置参数

描述 

默认值

框架堆内存(Framework Heap Memory)

taskmanager.memory.framework.heap.size

用于 Flink 框架的 JVM 堆内存(进阶配置)。

默认128M,不建议修改

任务堆内存(Task Heap Memory)

taskmanager.memory.task.heap.size

用于 Flink 应用的算子及用户代码的 JVM 堆内存。

无默认值

不建议配置,Flink框架会使用Flink总内存-堆内框架内存-网络内存-托管内存得出。(按照默认值,肯定低于Flink总内存的50%)

托管内存(Managed memory)

taskmanager.memory.managed.size

taskmanager.memory.managed.fraction

由 Flink 管理的用于排序、哈希表、缓存中间结果(批计算)以及 RocksDB State Backend 的本地内存(流计算)。受限Flink 总内存

无默认值

比例默认为0.4

框架堆外内存(Framework Off-heap Memory)

taskmanager.memory.framework.off-heap.size

用于 Flink 框架的堆外内存(直接内存或本地内存)(进阶配置)。

默认128M,不建议修改

任务堆外内存(Task Off-heap Memory)

taskmanager.memory.task.off-heap.size

用于 Flink 应用的算计及用户代码的堆外内存(直接内存或本地内存)。

默认是0

网络内存(Network Memory)

taskmanager.memory.network.min

taskmanager.memory.network.max

taskmanager.memory.network.fraction

用于任务之间数据传输的直接内存(例如网络传输缓冲)。该内存部分为基于 Flink 总内存的受限的等比内存部分。

最小是64M

最大是1G

比例是0.1,最终计算出来的值会限制在64M~1G

JVM Metaspace

taskmanager.memory.jvm-metaspace.size

Flink JVM 进程的 Metaspace。

默认256M

JVM 开销

 

taskmanager.memory.jvm-overhead.min

taskmanager.memory.jvm-overhead.max

taskmanager.memory.jvm-overhead.fraction

用于其他 JVM 开销的本地内存,例如栈空间、垃圾回收空间等。该内存部分为基于进程总内存的受限的等比内存部分。

最小192M

最大1G

比例是0.1

    网络内存这部分和Flink反压有关,后续有时间单独开篇文章说一下,这一块个人觉得还是蛮重要的。

 

 

用户如何配置内存:

    官网不建议同时设置进程总内存和 Flink 总内存。 这可能会造成内存配置冲突,从而导致部署失败。 额外配置其他内存部分时,同样需要注意可能产生的配置冲突。

要么配置进程总内存、要么配置Flink总内存、要么配置堆内内存+托管内存。个人觉得配置前两者比较靠谱,除非对Flink内部原理特别了解,否则没必要设置的那么细。

 

怎么判定TaskManager需要多少内存:

    咨询了下边上对Flink比较了解的同事,Flink应用内存只要够用就行了,配过多性能也不会再往上提升了,但是怎么知道够用呢?

    Flink中的数据全部存在状态中,即使是窗口的数据也存在窗口的State里面(这里面的数据不包括那些IO之间发来发去那些数据)。个人觉得可以这么搞,看CheckPoint的大小大概可以估算出State状态的大小,然后除以TaskManager的数量就大概可以知道每个TaskManager上保存的状态的大小,这部分用的JVM Heap中的Task Heap的大小,然后根据那个比例推测下整个Flink程序应该设置的大小。

    但CheckPoint的大小也得是在实际环境中跑起来观察一下才能拿到。个人认为可以这么搞,拿家里的10W条数据做个试验,看下Checkpoint的大小,然后配置下内存。到现场之后,等比例进行一定的配置就可以了。

    这样就可以大概估计下初始值,然后进行微调,或者还有一种野路子,直接拿少量的数据配置个比较大的内存,然后再按照上面的方法计算...好像这样还更加简单,哈哈哈

 

 

 

参考:

    https://ci.apache.org/projects/flink/flink-docs-release-1.10/zh/ops/memory/mem_setup.html