对于flink内存的设置,一般我们更关注taskmanager的设置,对于jobmanager,一般不会有内存分配的调优问题,而且相对更简单,本文就不再赘述相关配置,我们设置flink的taskmanager内存大小有三种方式:
(1)设置总内存:total process memory
(2)设置flink总内存:total flink memory
(3)设置各个中间组件本身内存
这里以第一种为例,本程序跑在yarn上,使用参数:-ytm 8192,也就是设置了8G的内存大小,执行时的内存分配方式如下:
这里有两种区分方式:
一是堆外内存和堆内内存来划分:
堆内内存包括flink框架执行所需的堆内存+task运行所需的堆内存。而总内存减去上面的堆内内存就是堆外内存了。
二是flink内存和其他内存
其他内存包括overhead和metaspace,总内存减去其他内存就是flink内存了,我们这里以第二种方式划分。
(1)总内存
首先,来到任务的Jobmanager 的configuration下面可以看到如下配置:
taskmanager.memory.process.size 8gb
说明了 -ytm 这个配置设置的是total process memory,整个taskmanager的内存加一起就是这个数。
(2)JVM overhead 内存
这部分内存呢,flink的任务是java程序是需要跑在jvm上的,但是jvm本身的启动运行也需要内存啊,所以这个配置是jvm本身运行时需要的内存,jvm启动需要内存的地方包括线程堆栈,IO,编译缓存等所需要的内存。这里是200M。
taskmanager.memory.jvm-overhead.max 200M
实际上,该值受到三个值的制约:
taskmanager.memory.jvm-overhead.max 最大值
taskmanager.memory.jvm-overhead.min 最小值
taskmanager.memory.jvm-overhead.fraction 比例
首先,使用fration * 总内存(total process memory) = 0.1 * 8G 差不多800多M,但是这时800M > taskmanager.memory.jvm-overhead.max,所以该值被拉回到200M。不过由于这里没法监控到这部分到底使用了多少,所以显示不出来,鼠标放在圆圈上会显示:
Metrics related to this configuration parameter cannot be monitored. Flink does not have full control over these memory pools.
(3)Jvm元空间
这是Java8之后将大部分永久代换成了元空间,大家都懂这部分,这里没有特别设置,默认使用了256M,主要受到该参数控制:
jobmanager.memory.jvm-metaspace.size
为什么先介绍overhead和metaspace呢,因为总的process内存减去这两部分内存就是flink total memory了。所以这里的
flink total memory = 8G - 200M - 256M
(4)netWork
网络,网络数据交换所需的堆外内存,如网络数据交换缓冲区。这里的值是200M,这里也是个比例值,这里不同于上面overhead的是,这里的值是:比例 * flink内存 而不是乘以总内存,所以计算方法是:
0.1 * (8G - 200M - 256M)
但是同样收到下面三个参数的制约:
taskmanager.memory.network.fraction 0.1 taskmanager.memory.network.max 200M taskmanager.memory.network.min 64mb
最大值不能超过200M,所以被卡在了200M。
(5)task off-heap
任务的堆外内存,默认是0,表示不使用堆外内存
(6)Framework Off-Heap
表示Flink框架本身使用的堆外内存大小,默认128M,由该参数控制,默认128M
taskmanager.memory.framework.off-heap.size
(7)Managed Memory
用于RocksDb的本地内存和批的排序,哈希表,缓存中间结果。该值也是个比例值,默认使用flink内存 * 0.4,由下面参数控制,注意这里也是乘以的flink内存而不是总内存。
taskmanager.memory.managed.fraction 默认0.4
taskmanager.memory.managed.size 默认没有设置
这里默认使用的是fraction来计算,但是该项目中设置了下面的size选项,设置了200M,所以显示的是200M,如果使用了RocksDb作为缓存组件,则应该适当增加该值的大小。而如果不使用RocksDb或者不需要缓存状态,则可将该值设为0.以便将有限的内存留给taskmanager
(8)Task Heap
真正跑任务需要的内存大小,总内存减去其他设置的内存大小就是任务能使用的大小了,这个内存是最重要的跑任务内存,所以在设置了总内存大小的时候,还有观察其他内存的占用情况,可能这里剩下的内存并没有想象的那么大了。
(9)Framework Heap
flink框架本身运行的内存大小,由该值控制,大小默认128M
taskmanager.memory.framework.heap.size