首页 > 解决方案 > Flink 作业在 yarn 上成功运行,但在 Kubernetes 上内存不足

问题描述

我们有一个 Flink 作业,它从 hive 读取数据并加入来自 kafka 的流数据。

它可以在 Yarn 上成功运行,但是当我们在 Kubernetes 上以完全相同的内存设置运行它时,它失败并出现错误

java.io.IOException: Insufficient number of network buffers: required 2, but only 1 available. The total number of network buffers is currently set to 57343 of 32768 bytes each. You can increase this number by setting the configuration keys 'taskmanager.memory.network.fraction', 'taskmanager.memory.network.min', and 'taskmanager.memory.network.max'.
\tat org.apache.flink.runtime.io.network.buffer.NetworkBufferPool.internalCreateBufferPool(NetworkBufferPool.java:340)
\tat org.apache.flink.runtime.io.network.buffer.NetworkBufferPool.createBufferPool(NetworkBufferPool.java:322)
\tat org.apache.flink.runtime.io.network.partition.ResultPartitionFactory.lambda$createBufferPoolFactory$0(ResultPartitionFactory.java:215)
\tat org.apache.flink.runtime.io.network.partition.ResultPartition.setup(ResultPartition.java:139)
\tat org.apache.flink.runtime.taskmanager.ConsumableNotifyingResultPartitionWriterDecorator.setup(ConsumableNotifyingResultPartitionWriterDecorator.java:88)
\tat org.apache.flink.runtime.taskmanager.Task.setupPartitionsAndGates(Task.java:869)
\tat org.apache.flink.runtime.taskmanager.Task.doRun(Task.java:635)
\tat org.apache.flink.runtime.taskmanager.Task.run(Task.java:543)
\tat java.lang.Thread.run(Thread.java:748)

我按照说明增加了taskmanager.memory.network.fraction,然后因为OOM而失败:

Caused by: java.lang.OutOfMemoryError: Java heap space
\tat java.nio.HeapByteBuffer.<init>(HeapByteBuffer.java:57)
\tat java.nio.ByteBuffer.allocate(ByteBuffer.java:335)
\tat di.flink.shadow.org.apache.parquet.bytes.HeapByteBufferAllocator.allocate(HeapByteBufferAllocator.java:32)
\tat di.flink.shadow.org.apache.parquet.hadoop.ParquetFileReader$ConsecutiveChunkList.readAll(ParquetFileReader.java:1166)
\tat di.flink.shadow.org.apache.parquet.hadoop.ParquetFileReader.readNextRowGroup(ParquetFileReader.java:805)
\tat org.apache.flink.formats.parquet.utils.ParquetRecordReader.readNextRecord(ParquetRecordReader.java:226)
\tat org.apache.flink.formats.parquet.utils.ParquetRecordReader.reachEnd(ParquetRecordReader.java:207)
\tat org.apache.flink.formats.parquet.ParquetInputFormat.reachedEnd(ParquetInputFormat.java:233)
\tat org.apache.flink.runtime.operators.DataSourceTask.invoke(DataSourceTask.java:193)
\tat org.apache.flink.runtime.taskmanager.Task.doRun(Task.java:719)
\tat org.apache.flink.runtime.taskmanager.Task.run(Task.java:543)
\tat java.lang.Thread.run(Thread.java:748)

我什至将 Kubernetes 上的任务管理器进程大小从 16gb 增加到 32gb,仍然出现相同的错误,通过查看 Kubernetes pod 资源使用指标,有 3-5 个 pod 消耗的内存比平均水平多得多,并且它们的内存使用量保持不变在运行时增长。

我想知道 Kubernetes 上的内存使用是否存在任何已知问题,尤其是网络缓冲区,我在哪里可以检查这些指标以进行调试?

标签: kubernetesapache-flink

解决方案


我发现了问题,在 docker 入口点脚本中,任务管理器会做

TASK_MANAGER_NUMBER_OF_TASK_SLOTS=${TASK_MANAGER_NUMBER_OF_TASK_SLOTS:-$(grep -c ^processor /proc/cpuinfo)}

在 flink-conf 中覆盖 taskmanager.numberOfTaskSlots,但是在 /proc/cpuinfo 中包含所有物理 cpu 核心,但不仅包含分配给容器的核心,因此在我的情况下,taskmanager.numberOfTaskSlots 已设置为 32 并导致一些容器需要做大部分工作,而其余的都是免费的。


推荐阅读