在大数据领域,大多数开源框架(Hadoop、Spark、Storm)都是基于 JVM 运行,但是 JVM 的内存管理机制往往存在着诸多类似 OutOfMemoryError 的问题,主要是因为创建过多 的对象实例而超过 JVM 的最大堆内存限制,却没有被有效回收掉,这在很大程度上影响了系 统的稳定性,尤其对于大数据应用,面对大量的数据对象产生,仅仅靠 JVM 所提供的各种垃 圾回收机制很难解决内存溢出的问题。在开源框架中有很多框架都实现了自己的内存管理, 例如 Apache Spark 的 Tungsten 项目,在一定程度上减轻了框架对 JVM 垃圾回收机制的依赖, 从而更好地使用 JVM 来处理大规模数据集。

Flink 也基于 JVM 实现了自己的内存管理,将 JVM 根据内存区分为 Unmanned Heap、Flink Managed Heap、Network Buffers 三个区域。在 Flink 内部对 Flink Managed Heap 进行管 理,在启动集群的过程中直接将堆内存初始化成 Memory Pages Pool,也就是将内存全部以 二进制数组的方式占用,形成虚拟内存使用空间。新创建的对象都是以序列化成二进制数据 的方式存储在内存页面池中,当完成计算后数据对象 Flink 就会将 Page 置空,而不是通过 JVM 进行垃圾回收,保证数据对象的创建永远不会超过 JVM 堆内存大小,也有效地避免了因 为频繁 GC 导致的系统稳定性问题。
Flink性能优化之Flink内存优化_数据

1.JobManager 配置

JobManager 在 Flink 系统中主要承担管理集群资源、接收任务、调度 Task、收集任务 状态以及管理 TaskManager 的功能,JobManager 本身并不直接参与数据的计算过程中,因 此 JobManager 的内存配置项不是特别多,只要指定 JobManager 堆内存大小即可。 jobmanager.heap.size:设定JobManager堆内存大小,默认为1024MB。

2.TaskManager 配置

TaskManager作为Flink集群中的工作节点,所有任务的计算逻辑均执行在TaskManager 之上,因此对 TaskManager 内存配置显得尤为重要,可以通过以下参数配置对 TaskManager 进行优化和调整。对应的官方文档是:
Flink性能优化之Flink内存优化_数据_02

  • taskmanager.heap.size:设定 TaskManager 堆内存大小,默认值为 1024M,如果在 Yarn 的集群中,TaskManager 取决于 Yarn 分配给 TaskManager Container 的内存大小,且 Yarn 环境下一般会减掉一部分内存用于 Container 的容错。
  • taskmanager.jvm-exit-on-oom:设定 TaskManager 是否会因为 JVM 发生内存溢出而停 止,默认为 false,当 TaskManager 发生内存溢出时,也不会导致 TaskManager 停止。
  • taskmanager.memory.size:设定 TaskManager 内存大小,默认为 0,如果不设定该值 将会使用 taskmanager.memory.fraction 作为内存分配依据。
  • taskmanager.memory.fraction:设定 TaskManager 堆中去除 Network Buffers 内存后的内存分配比例。该内存主要用于 TaskManager 任务排序、缓存中间结果等操作。例如, 如果设定为 0.8,则代表 TaskManager 保留 80%内存用于中间结果数据的缓存,剩下 20% 的 内 存 用 于 创 建 用 户 定 义 函 数 中 的 数 据 对 象 存 储 。 注 意 , 该 参 数 只 有 在 taskmanager.memory.size 不设定的情况下才生效。
  • taskmanager.memory.off-heap:设 置是 否开 启堆 外内 存供 Managed Memory 或 者 Network Buffers 使用。
  • taskmanager.memory.preallocate:设置是否在启动 TaskManager 过程中直接分配 TaskManager 管理内存。
  • taskmanager.numberOfTaskSlots:每个 TaskManager 分配的 slot 数量。