问题描述

Flink 版本:1.13.6

部署模式:Flink On YARN Application Mode

当 Flink 作业在 YARN 上运行了几天之后,容器会因为物理内存使用超出物理内存限制而被杀死,并报如下错误:

1
2
3
4
5
6
7
8
9
2022-08-12 12:36:04,168 WARN  akka.remote.ReliableDeliverySupervisor                       [] - Association with remote system [akka.tcp://flink@flink-node-06:42477] has failed, address is now gated for [50] ms. Reason: [Association failed with [akka.tcp://flink@flink-node-06:42477]] Caused by: [java.net.ConnectException: Connection refused: flink-node-06/10.10.17.255:42477]
2022-08-12 12:36:04,844 INFO org.apache.flink.runtime.resourcemanager.active.ActiveResourceManager [] - Worker container_e48_1655606936581_0285_01_000006 is terminated. Diagnostics: [2022-08-12 12:36:02.281]Container [pid=30100,containerID=container_e48_1655606936581_0285_01_000006] is running 65536B beyond the 'PHYSICAL' memory limit. Current usage: 2.0 GB of 2 GB physical memory used; 3.8 GB of 8 GB virtual memory used. Killing container.
Dump of the process-tree for container_e48_1655606936581_0285_01_000006 :
|- PID PPID PGRPID SESSID CMD_NAME USER_MODE_TIME(MILLIS) SYSTEM_TIME(MILLIS) VMEM_USAGE(BYTES) RSSMEM_USAGE(PAGES) FULL_CMD_LINE
|- 30100 30094 30100 30100 (bash) 0 0 118177792 369 /bin/bash -c /usr/java/jdk1.8.0_211-amd64/bin/java -Xmx697932173 -Xms697932173 -XX:MaxDirectMemorySize=300647712 -XX:MaxMetaspaceSize=268435456 -Dlog.file=/data/hadoop/yarn/log/application_1655606936581_0285/container_e48_1655606936581_0285_01_000006/taskmanager.log -Dlog4j.configuration=file:./log4j.properties -Dlog4j.configurationFile=file:./log4j.properties org.apache.flink.yarn.YarnTaskExecutorRunner -D taskmanager.memory.network.min=166429984b -D taskmanager.cpu.cores=1.0 -D taskmanager.memory.task.off-heap.size=0b -D taskmanager.memory.jvm-metaspace.size=268435456b -D external-resources=none -D taskmanager.memory.jvm-overhead.min=214748368b -D taskmanager.memory.framework.off-heap.size=134217728b -D taskmanager.memory.network.max=166429984b -D taskmanager.memory.framework.heap.size=134217728b -D taskmanager.memory.managed.size=665719939b -D taskmanager.memory.task.heap.size=563714445b -D taskmanager.numberOfTaskSlots=1 -D taskmanager.memory.jvm-overhead.max=214748368b --configDir . -Djobmanager.rpc.address='flink-node-02' -Dpipeline.classpaths='' -Dweb.port='0' -Djobmanager.memory.off-heap.size='134217728b' -Dweb.tmpdir='/tmp/flink-web-5deb359d-87fb-49e3-bf4a-a9214dc667e8' -Djobmanager.rpc.port='44848' -Drest.address='flink-node-02' -Djobmanager.memory.jvm-overhead.max='201326592b' -Djobmanager.memory.jvm-overhead.min='201326592b' -Dtaskmanager.resource-id='container_e48_1655606936581_0285_01_000006' -Dexecution.target='embedded' -Dinternal.taskmanager.resource-id.metadata='flink-node-06:45454' -Dpipeline.jars='file:/data/hadoop/yarn/local/usercache/hadoop/appcache/application_1655606936581_0285/container_e48_1655606936581_0285_01_000001/flink_dw_prod.jar' -Djobmanager.memory.jvm-metaspace.size='268435456b' -Djobmanager.memory.heap.size='469762048b' 1> /data/hadoop/yarn/log/application_1655606936581_0285/container_e48_1655606936581_0285_01_000006/taskmanager.out 2> /data/hadoop/yarn/log/application_1655606936581_0285/container_e48_1655606936581_0285_01_000006/taskmanager.err
|- 30175 30100 30100 30100 (java) 1236701 120868 3967287296 523935 /usr/java/jdk1.8.0_211-amd64/bin/java -Xmx697932173 -Xms697932173 -XX:MaxDirectMemorySize=300647712 -XX:MaxMetaspaceSize=268435456 -Dlog.file=/data/hadoop/yarn/log/application_1655606936581_0285/container_e48_1655606936581_0285_01_000006/taskmanager.log -Dlog4j.configuration=file:./log4j.properties -Dlog4j.configurationFile=file:./log4j.properties org.apache.flink.yarn.YarnTaskExecutorRunner -D taskmanager.memory.network.min=166429984b -D taskmanager.cpu.cores=1.0 -D taskmanager.memory.task.off-heap.size=0b -D taskmanager.memory.jvm-metaspace.size=268435456b -D external-resources=none -D taskmanager.memory.jvm-overhead.min=214748368b -D taskmanager.memory.framework.off-heap.size=134217728b -D taskmanager.memory.network.max=166429984b -D taskmanager.memory.framework.heap.size=134217728b -D taskmanager.memory.managed.size=665719939b -D taskmanager.memory.task.heap.size=563714445b -D taskmanager.numberOfTaskSlots=1 -D taskmanager.memory.jvm-overhead.max=214748368b --configDir . -Djobmanager.rpc.address=flink-node-02 -Dpipeline.classpaths= -Dweb.port=0 -Djobmanager.memory.off-heap.size=134217728b -Dweb.tmpdir=/tmp/flink-web-5deb359d-87fb-49e3-bf4a-a9214dc667e8 -Djobmanager.rpc.port=44848 -Drest.address=flink-node-02 -Djobmanager.memory.jvm-overhead.max=201326592b -Djobmanager.memory.jvm-overhead.min=201326592b -Dtaskmanager.resource-id=container_e48_1655606936581_0285_01_000006 -Dexecution.target=embedded -Dinternal.taskmanager.resource-id.metadata=flink-node-06:45454 -Dpipeline.jars=file:/data/hadoop/yarn/local/usercache/hadoop/appcache/application_1655606936581_0285/container_e48_1655606936581_0285_01_000001/flink_dw_prod.jar -Djobmanager.memory.jvm-metaspace.size=268435456b -Djobmanager.memory.heap.size=469762048b

[2022-08-12 12:36:02.322]Container killed on request. Exit code is 143
[2022-08-12 12:36:02.330]Container exited with a non-zero exit code 143.

该作业在 Flink History Server 的详情界面的 Exceptions 标签下可以看到以下错误信息:

1
Caused by: org.apache.flink.runtime.io.network.netty.exception.RemoteTransportException: Connection unexpectedly closed by remote task manager 'flink-node-06/10.10.18.25:16407'. This might indicate that the remote task manager was lost.

在 Exceptions 下的错误信息可以看到 Flink 集群的一个 TaskManager 节点连接不上。从 YARN 错误日志可以看出,该 TaskManager 节点连接不上,是因为 TaskManager 内存使用大小超出了容器的限制而被杀死。

既然问题是 TaskManager 内存不足引起的,那么尝试通过增加 TaskManager 内存的方式来解决该问题,将 TaskManager 内存由原来的 2048m 增加到 3072m,再次运行该作业,但它仍然每隔几天就报同样的错误。

调大 TaskManager 运行内存后,作业的启动参数如下:

1
-Djobmanager.memory.process.size=1024m -Dtaskmanager.memory.process.size=3072m

问题分析

YARN 日志的异常信息表明 TaskManager 消耗的内存比预期的要多。虽然 TaskManager 因为内存超限运行被 YARN 杀死,并不代表这里有内存泄漏。

我们知道,Flink 集群上的 TaskManager 本质上还是一个 Java 程序。Java 程序可能会消耗各种类型的内存:堆、直接、本地、元空间。在所有这些类型的内存当中,除了本地内存外,Flink 通过 JVM 参数设置了明确的上限,因此如果进程尝试使用超过限制的内存,则会抛出 OutOfMemoryError。但在 YARN 日志中并没有 OOM 相关的异常信息,唯一的可能是 Flink 使用了比计划更多的本地内存。

所以,这里再尝试增加 JVM Overhead 内存占比,让 Flink 在容器中预留更多的本地内存。

解决方案

通过设置 taskmanager.memory.jvm-overhead.fraction 参数来增加 JVM Overhead 内存占比,以达到在容器中预留更多的本地内存。该参数的默认值为 0.1,修改为 0.2 后,重新启动该作业,后续观察该作业的运行情况,没有再出现因为内存超限运行被 YARN 杀死的异常。

修改后作业的启动参数如下:

1
-Djobmanager.memory.process.size=1024m -Dtaskmanager.memory.process.size=3072m -Dtaskmanager.memory.jvm-overhead.fraction=0.2

(END)