Apache Flink 通过严格控制其各个组件的内存使用,在 JVM 之上提供了高效的工作负载。虽然社区努力为所有配置提供合理的默认值,但不可能适用于用户在 Flink 上部署的所有应用程序。为了向我们的用户提供最大的生产价值,Flink 允许在集群内进行高级和细粒度的内存分配调优。
我们都知道不管 Flink 运行在什么集群上,真正干活的都是 TaskManager (后面简称为 TM),JobManager (后面简称为 JM)只负责任务的调度,所以了解 TM 的内存模型是非常有必要的,今天这篇文章就来说一下 TM 的内存模型,JM 的内存模型相对简单,这里就不再说了.
在 Flink 1.10.0 版本中,社区对 TM 的内存模型做了进一步的改进和升级,虽然内存的划分已经很明确,但还是让人看的眼花缭乱,容易混淆.先来看下面这张图.
image-20210403163557657
在 Flink 1.12.0 版本中对 UI 进行了改进,在 TM 的页面增加了一个内存模型图,清楚的显示了每个区域的内存配置以及使用情况.
★
Total Process Memory (进程总内存) 包含了 Flink 应用程序使用的全部内存资源:Total Flink Memory (Flink应用使用的内存) + 运行 Flink JVM 使用的内存。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 (网络内存)
”
下面就按照上图中编号顺序分别介绍一下这些内存的作用以及如何配置
Flink 框架本身占用的内存,这部分的内存一般情况下是不需要修改的,在特殊的情况下可能需要调整.
用于 Flink 应用的算子及用户代码占用的内存。
纯堆外内存,由 MemoryManager 管理,用于中间结果缓存、排序、哈希表等,以及 RocksDB 状态后端。可见,RocksDB 消耗的内存可以由用户显式控制了,不再像旧版本一样难以预测和调节。
Network Memory 使用的是 Directory memory,在 Task 与 Task 之间进行数据交换时(shuffle),需要将数据缓存下来,缓存能够使用的内存大小就是这个 Network Memory。它是由三个参数决定.
从 JDK 8 开始,JVM 把永久代拿掉了。类的一些元数据放在叫做 Metaspace 的 Native Memory 中。在 Flink 中的 JVM Metaspace Memory 也一样,它配置的是 Task Manager JVM 的元空间内存大小。
保留给 JVM 其他的内存开销。例如:Thread Stack、code cache、GC 回收空间等等。和 Network Memory 的配置方法类似。它也由三个配置决定
我们再来看一下 TM 启动日志里面内存相关的配置信息如下:
INFO org.apache.flink.yarn.YarnTaskExecutorRunner [] - Program Arguments:
INFO org.apache.flink.yarn.YarnTaskExecutorRunner [] - -D
INFO org.apache.flink.yarn.YarnTaskExecutorRunner [] - taskmanager.memory.framework.off-heap.size=134217728b(128M)
INFO org.apache.flink.yarn.YarnTaskExecutorRunner [] - -D
INFO org.apache.flink.yarn.YarnTaskExecutorRunner [] - taskmanager.memory.network.max=214748368b(204.8M)
INFO org.apache.flink.yarn.YarnTaskExecutorRunner [] - -D
INFO org.apache.flink.yarn.YarnTaskExecutorRunner [] - taskmanager.memory.network.min=214748368b(204.8M)
INFO org.apache.flink.yarn.YarnTaskExecutorRunner [] - -D
INFO org.apache.flink.yarn.YarnTaskExecutorRunner [] - taskmanager.memory.framework.heap.size=134217728b(128M)
INFO org.apache.flink.yarn.YarnTaskExecutorRunner [] - -D
INFO org.apache.flink.yarn.YarnTaskExecutorRunner [] - taskmanager.memory.managed.size=858993472b(819.2M)
INFO org.apache.flink.yarn.YarnTaskExecutorRunner [] - -D
INFO org.apache.flink.yarn.YarnTaskExecutorRunner [] - taskmanager.cpu.cores=4.0
INFO org.apache.flink.yarn.YarnTaskExecutorRunner [] - -D
INFO org.apache.flink.yarn.YarnTaskExecutorRunner [] - taskmanager.memory.task.heap.size=805306352b(767.9M)
INFO org.apache.flink.yarn.YarnTaskExecutorRunner [] - -D
INFO org.apache.flink.yarn.YarnTaskExecutorRunner [] - taskmanager.memory.task.off-heap.size=0b这个内存就是上图中 Configured Values 显示的值,我们把这些值加起来 taskmanager.memory.framework.off-heap.size + taskmanager.memory.network.max + taskmanager.memory.framework.heap.size + taskmanager.memory.managed.size + taskmanager.memory.task.heap.size = 128 + 205 + 128 + 819 + 768 = taskmanager.memory.flink.size = 2048M 这个结果跟我们在 flink-conf.yaml 中的配置是能对上的.
上面这么多的内存,到底应该怎么配置呢?首先官网不建议同时设置进程总内存和 Flink 总内存。这可能会造成内存配置冲突,从而导致部署失败。额外配置其他内存部分时,同样需要注意可能产生的配置冲突。
其实 taskmanager.memory.framework.heap.size ,taskmanager.memory.framework.off-heap.size,JVM Metaspace,JVM Overhead 这几个参数一般情况下是不需要配置的,走默认值就可以了.我们主要关注的是 Task Heap、Managed Memory、Network 这几部分的内存,当然 Flink 本身也会计算出这 3 部分的内存,我们自己也需要根据任务的特点,比如流量大小,状态大小等去调整.
Flink SQL 如何实现列转行?
Flink SQL 结合 HiveCatalog 使用
Flink SQL 解析嵌套的 JSON 数据
Flink SQL 中动态修改 DDL 的属性
Flink WindowAssigner 源码解析
Flink 1.11.x WatermarkStrategy 不兼容问题
如果你觉得文章对你有帮助,麻烦点一下赞和在看吧,你的支持是我创作的最大动力.
| 留言与评论(共有 0 条评论) “” |