hi,xintong,

我是 zhisheng,留意到你在回答 Flink 1.10 中到内存分配的问题,刚好我也继续问一个我的疑问。因为我在 YadongXie
<https://cwiki.apache.org/confluence/display/~vthinkxie> 发起的 FLIP-102
中关于 TaskManager UI 内存分配的展示,Non-heap 主要是由 MetaSpace 和 Overhead 组成的,如下图所示:

http://zhisheng-blog.oss-cn-hangzhou.aliyuncs.com/2020-03-09-152736.png

在 FLIP-49 中看到 MetaSpace 和 Overhead 的默认配置和 fraction,看得出其实这两者加起来的值应该不会很大。

http://zhisheng-blog.oss-cn-hangzhou.aliyuncs.com/2020-03-09-153057.png

另外还从 FLIP-49 memory calculations 看到了内存的计算方式如下图所示,

http://zhisheng-blog.oss-cn-hangzhou.aliyuncs.com/2020-03-09-153618.png

从上面这个图中的分配值加起来看,数值应该也不会很大,但是我自己本地 Mac 电脑起了一个 standalone 的 Flink,Non-Heap
占的比例很大,截图如下:

http://zhisheng-blog.oss-cn-hangzhou.aliyuncs.com/2020-03-09-154154.png

从上面的截图中可以发现 Non-heap Max 是 1.33 GB,而整个 Heap 是 1.83 GB。说到这个 Heap
这么大,我的问题又来了,flink-conf.yaml 中 taskmanager.memory.process.size: 1568m
这个参数我没改动,了解到这个参数是表示 Total Process memory,应该该值已经是最大的内存值了,其他的加起来应该不会再超过这个值了。
种种疑问🤔️加起来就比较郁闷了,下面我总结下我的疑问,还望辛童可以有空的时候可以答疑一下,感谢🙏。

总结下我的问题:

1、Non-Heap 那个 UI 上展示的是否是 MetaSpace 和 Overhead 加起来的值?

2、为什么本地起的 Standalone Flink,为啥 UI 上展示的 Heap
会超过设置的 taskmanager.memory.process.size 的值?

3、默认 Flink 自身的配置下,启动 Flink 1.9 和
1.10,运行相同的作业他们性能之间的差距大概是什么样的?如果上生产是否可以使用默认的内存配置?会不会堆内存有点小了?这个我说下我自己简单测试了下
Flink 1.9 和 1.10 下运行同一个有状态的作业,他们的 GC 情况差别还挺大的。1.10 Young GC 次数差不多是 1.9 的两倍。

Xintong Song <tonysong...@gmail.com> 于2020年3月9日周一 下午6:39写道:

> >
> > 图1中的Direct类型里面所包含的framework offheap、task offheap以及shuffle就是您讲的“不在 JVM
> > 堆上但受到 JVM 管理的内存:Direct”么?
>
> 是的
>
>
> > 这部分内存是可以知道其使用情况并在metrics里看到的么?
>
> 应该是与metrics中的Direct是对应的(因为绝大多数情况我们没有使用Mapped Buffer),这里细节我记不太清楚了最好再确认下。
>
> 另外,flink 1.10里将RocksDBStateBackend改为使用managed memory,不过网页上显示的是managed
> > memory统一使用offheap内存,您的解答里说的是native内存,不知道是不是您说的“完全不受 JVM 管理的内存:Native”这个?
>
> 是的
>
> 不是太清楚offheap和direct以及native的关系是怎样的
>
> Flink 配置项中的 task/framework offheap,是包括了 direct 和 native
> 内存算在一起的,也就是说用户不需要关心具体使用的是 direct 还是 native。
>
> 最后,我在官网上看managed memory和network buffers在作业启动后会有变化
>
>
> 能把具体的页面链接发一下吗,可能指的是1.9以前的情况,1.10是不会变化的。1.9以前的话,TM会在进程启动并初始化之后触发一次GC,然后以GC后的空闲内存作为Heap内存重新算一遍managed、network内存应该多大。
>
> Thank you~
>
> Xintong Song
>
>
>
> On Mon, Mar 9, 2020 at 3:23 PM pkuvisdudu <zjkingdom2...@163.com> wrote:
>
> > 非常详细的解答,非常感谢~~
> >
> > 还有一些小疑问。图1中的Direct类型里面所包含的framework offheap、task offheap以及shuffle就是您讲的“不在
> > JVM 堆上但受到 JVM 管理的内存:Direct”么?这部分内存是可以知道其使用情况并在metrics里看到的么?
> >
> > 另外,flink 1.10里将RocksDBStateBackend改为使用managed memory,不过网页上显示的是managed
> > memory统一使用offheap内存,您的解答里说的是native内存,不知道是不是您说的“完全不受 JVM
> > 管理的内存:Native”这个?不是太清楚offheap和direct以及native的关系是怎样的
> >
> > 最后,我在官网上看managed memory和network
> > buffers在作业启动后会有变化,但我一直看不懂是咋变化的😂,不知道这里能否解答一下
> >
> > 再次感谢详细的解答~~
> >
> >
> >
> >
> > | |
> > 张江
> > |
> > |
> > 邮箱:zjkingdom2...@163.com
> > |
> >
> > 签名由 网易邮箱大师 定制
> >
> > 在2020年03月09日 11:22,Xintong Song 写道:
> > Hi,
> >
> >
> > 关于你的几个问题:
> >
> >
> > 1. 关于 JVM 的内存,堆内存(Heap Memory)的定义通常是比较清晰的,但堆外/非堆内存(Off-Heap/Non-Heap
> > Memory)的定义却有很多不同的版本,这应该是导致你困惑的主要原因。让我们先抛开这些名词,本质上 Java 应用使用的内存(不包括 JVM
> > 自身的开销)可以分为三类:
> > JVM 堆内存:Heap
> > 不在 JVM 堆上但受到 JVM 管理的内存:Direct
> > 完全不受 JVM 管理的内存:Native
> > Direct 内存是直接映射到 JVM 虚拟机外部的内存空间,但是其用量又受到 JVM 的管理和限制,从这个角度来讲,认为它是 JVM 内存或者非
> > JVM 内存都是讲得通的。
> >
> >
> > 关于 Off-Heap/Non-Heap,广义上讲只要不是 Heap 内存就可以称为 Non-Heap,但是我们经过实验发现 MXBean 的
> > Non-Heap 是不包括 Direct,而是由 Code Cache、Metaspace、Compressed Class Space
> > 几个部分组成。FLIP-102 讨论的是 metrics 如何在 WebUI 上展示,Flink metrics 是通过 MXBean
> > 获取的,因此图一展示的 Non-Heap 是与 MXBean 的 Non-Heap 定义的。
> >
> >
> > 2. Heap/Non-Heap 前面已经介绍过,而 Direct/Mapped 则同样是通过 MXBean 统计两个 Buffer Pool
> > 的情况。这里的 Direct 指的是 Direct Buffer Pool 而不是 Direct Memory,这两个 Buffer Pool
> 都是受
> > -XX:MaxDirectMemorySize 控制的,可以认为都是 Direct Memory 的一部分。
> >
> >
> > 这几个 metrics 加在一起不是 TM 的总内存,一方面是因为 Native 内存没有被算进去(也就是 Cut-off 的主要部分),因为
> > Native 是不受 JVM 管理的,MXBean 完全不知道它的使用情况。另一方面,JVM
> 自身的开销也并不是都被覆盖到了,比如对于栈空间,JVM
> > 只能限制每个线程的栈空间有多大,但是不能限制线程的数量,因此总的栈空间大小也是不受控制的,也没有通过 Metric 来体现。
> >
> >
> > 总的来说,JVM 的内存机制是非常复杂的,且并不是每一个部分都能够由用户参数控制的。Flink 1.10
> > 简化了内存模型,目的是让用户不需要去关心这其中的细节,只关注 Flink 各功能模块所需的相关内存大小即可。而目前在 1.10 中的 metric
> > 是比较缺失的无法完全描述 Flink 的内存使用情况,社区提出 FLIP-102 梳理 metrics 及 UI
> > 展示也正是为了解决这个问题。但即便如此,受 JVM 内存机制本身的限制,恐怕也很难做到每个部分都完全匹配到对应的 metrics 上。
> >
> >
> > 3. 这个应该是存在 state 里的,具体用哪种类型的内存取决于你的 State Backend
> > 类型。MemoryStateBackend/FsStateBackend 用的是 Heap 内存,RocksDBStateBackend 用的是
> > Native 内存,也就是 1.10 中的 Manage Memory。
> >
> >
> >
> > Thank you~
> >
> > Xintong Song
> >
> >
> >
> >
> >
> > On Sun, Mar 8, 2020 at 4:49 PM pkuvisdudu <zjkingdom2...@163.com> wrote:
> >
> >  Hi all,
> >
> >
> > 我是Flink新人,最近在看一些flink资源管理机制的知识,有3个内存类型方面的问题想请教大家:
> >
> >
> > 1.
> >
> Flink的内存类型如下图1所示,其中Heap内存和NonHeap内存由JVM管理,我想问一下Direct内存是否也是由JVM管理?因为我同时也看到过图2所示的内存类型,上面标示的是JVM
> > Direct,但在FLIP102里看到的是属于Outside JVM,所以现在有点困惑。另外,我从相关页面上只看到了Network
> buffers,
> > Managed memory, Heap的计算方法,但不知道按照图1所示的内存类型,Direct内存和NonHeap是怎么计算分配的?
> > 图1
> > 图2
> > 2. Flink metrics里展示的内存方面的信息以Status.JVM.Memory为前缀,包含Heap, NonHeap, Direct,
> >
> Mapped四种。我测试过,这四种内存Used之和应该并不是TM真正所使用的总内存。那么TM使用的总内存还包括哪些,是在哪里用到的?(不知道是不是cut-off那部分使用的内存?)Flink
> > 1.10似乎对内存进行了更细致的划分和分配,但在metrics里展示的内配置和使用信息还是跟1.9一样的么?
> > 3. Window相关的算子会将窗口内的数据作为状态保存在内存里,等待窗口触发再进行计算。想问一下这里的状态是存在哪种类型的内存里面?
> >
> >
> > 祝好,
> >
> >
> >
> >
> >
>

回复