Flink 1.11 JobManager 内存管理优化

Flink 1.11

Apache Flink 1.11 对 JobManagers 的内存模型和配置选项进行了重大调整。这些最近引入的调整能使 Flink 更加适应各种部署环境(例如 Kubernetes、Yarn、Mesos),并对内存消耗提供严格的控制。上一篇博文重点介绍了 TaskManager 的内存模型以及它在 Flink 1.10 中的改进。这篇文章讨论了相同的主题,但对象变成了 JobManager。Flink 1.11 统一了 Flink 进程内存模型。JobManager 新引入的内存模型与 TaskManager 的类似,不过 JobManager 的更简单,组件也更少。因此,这篇文章可能看起来与我们之前关于 Flink 内存的内容非常相似,但这篇文章目的是提供对 Flink 1.11 中的 JobManager 内存模型的完整概述。

清楚的了解 Apache Flink 的进程内存模型可以让我们更有效地管理各种工作负载。下图描述了 Flink 进程的主要内存组件:

Task Manager 进程是一个 JVM 进程。从高层次上理解,它的内存由 JVM Heap 和 Off-Heap 内存组成。这些类型的内存由 Flink 直接使用或用于 JVM 特殊目的(例如,metaspace 等)。Flink 中有两个主要的内存消费方:作业算子任务的用户代码以及框架本身(内部数据结构、网络缓冲区等)。

JobManager 进程是一个 JVM 进程。从高层次上理解,它的内存由 JVM Heap 和 Off-Heap 内存组成。这些类型的内存由 Flink 直接使用或用于 JVM 特殊目的(例如,metaspace 等)。 JobManager 进程中有两个主要的内存消费方:框架本身(内部数据结构、网络缓冲区等)以及运行在 JobManager 进程中的用户代码。

请注意,用户代码可以直接访问所有类型的内存:JVM Heap、Direct 内存以及 Native 内存。因此,Flink 无法真正控制分配以及使用。

2. 如何配置 JobManager 内存

随着 Flink 1.11 的最新发布,为了提供更好的用户体验,框架对内存组件进行了高层次和细粒度的优化。Flink 社区引入了三种在 JobManager 中配置内存方法。为 JobManager 的 JVM 进程配置可用的总内存,需要配置以下两个选项,也是最简单的两个选项:

  • Total Process Memory:Flink Java 应用程序(包括用户代码)以及为 JVM 运行整个进程所消耗的总内存。
  • Total Flink Memory:仅 Flink Java 应用程序消耗的内存,包括用户代码,但不包括为 JVM 运行分配的内存。

建议为 Standalone 部署配置 Total Flink Memory,明确为 Flink 声明分配多少内存是一种常见做法,而外部 JVM 开销则无关紧要。对于在容器化环境(如 Kubernetes、Yarn 或 Mesos)中部署 Flink,推荐使用 Total Process Memory 选项,因为变成了请求容器的总内存大小。容器化环境通常会严格执行此内存上限。

如果您想对 JVM Heap 的大小进行更细粒度的控制,可以直接配置第三个选项。这种方法明确区分了堆内存和任何其他内存类型。

其余的内存组件会根据其默认值或者额外配置的参数来自动调整。Flink 还会检查整体一致性。您可以在相应的文档中找到有关不同内存组件的更多信息。

此外,您可以单独配置 Off-Heap 内存(JVM Direct 和非 Direct 内存)以及 JVM metaspace 和 JVM overhead。JVM overhead 是总进程内存的一小部分。JVM overhead 的配置方式与我们之前关于 TaskManager 内存模型的博文中描述类似。

3. 控制容器内存上限的更多提示

Heap 和 Direct 内存使用由 JVM 管理。在 Apache Flink 或其用户应用程序中还有许多其他可能的 Native 内存消耗来源,这些来源并不受 Flink 或 JVM 管理。控制它们的上限通常很困难,这使得调试潜在的内存泄漏变得很复杂。如果 Flink 的进程以不受管理的方式分配过多内存,通常会导致在容器化环境中杀死 Task Manager 容器。在这种情况下,可能很难排查是哪种类型的内存消耗超过了上限。Flink 1.11 引入了一些特定的调优选项来清楚地表示这些组件。虽然 Flink 不能始终执行严格的上限和边界,但这里的想法是明确规划内存使用。下面我们提供了一些示例来说明如何设置内存以防止容器超出其内存上限:

  • 用户代码或其依赖项会消耗大量的 Off-Heap 内存。调整 Off-Heap 选项可以为用户代码以及其依赖项分配额外的 Direct 或 Native 内存。Flink 无法控制 Native 内存的分配,但它可以为 JVM Direct 内存分配设置上限。Direct 内存限制由 JVM 强制执行。
  • JVM Metaspace 需要额外的内存。如果遇到 OutOfMemoryError: Metaspace,Flink 提供了增加其上限的选项,由 JVM 确保不超过该上限。Flink JVM 进程的 metaspace 大小要明确设置,不能使用默认的 JVM 设置。
  • JVM 需要更多的内部内存。对某些类型的 JVM 进程分配没有办法直接控制,但 Flink 提供了 JVM 开销选项。这些选项允许声明额外的内存量,这些内存是为这些分配所预期的,并且未被其他选项覆盖。

4. 结论

最新版本的 Flink(Flink 1.11)对内存配置进行了一些重大调整,使您可以比以前更好地管理应用程序内存和调试 Flink。

欢迎关注我的公众号和博客:

原文:Memory Management improvements for Flink’s JobManager in Apache Flink 1.11

赏几毛白!