【问题标题】:Nifi 1.6.0 memory leakNifi 1.6.0 内存泄漏
【发布时间】:2018-10-30 03:39:38
【问题描述】:

我们正在生产环境中运行 NiFi 1.6.0 的 Docker 容器,并且不得不遇到内存泄漏问题。

一旦启动,应用程序运行良好,但是在 4-5 天后,主机上的内存消耗不断增加。在 NiFi 集群 UI 中检查时,JVM 堆大小几乎没有使用 30% 左右,但操作系统级别的内存达到 80-90%。

在运行 docker starts 命令时,我们发现 NiFi docker 容器正在消耗内存。

收集 JMX 指标后,我们发现 RSS 内存不断增长。这可能是什么潜在原因?在集群对话框的 JVM 选项卡中,年轻 GC 似乎也在及时发生,旧 GC 计数显示为 0。

我们如何确定导致 RSS 内存增长的原因?

【问题讨论】:

  • 您是否已经开始查看堆转储?您有理由怀疑应用程序源中的任何内容都在泄漏内存?你能提供一个minimal reproducible example 一个有用的应用程序源子集吗?
  • 除了上面列出的项目之外,您使用的是 Apache NiFi 提供的便利二进制文件(例如hub.docker.com/r/apache/nifi)还是自定义图像?
  • @DavidMaze,我现在没有头文件,但我肯定可以提取它。 docker 容器正在运行github.com/apache/nifi,使用它的预构建处理器并执行脚本处理器。
  • @apiri 我们已经编写了我们的 Dockerfile,它与 docker hub 上的几乎相同,只是入口点发生了变化。
  • 更多关于你的执行脚本处理器的细节会很有趣。如果您能够分享他们正在做的事情,那么那里可能会有一些东西。堆转储会很有帮助,尤其是在条件衰减时以周期性方式进行

标签: docker memory-leaks apache-nifi


【解决方案1】:

您需要在非 docker 环境中复制它,因为使用 docker,内存为 known to raise
正如我在“Difference between Resident Set Size (RSS) and Java total committed memory (NMT) for a JVM running in Docker container”中解释的那样,docker 存在一些错误(如issue 10824issue 15020),这些错误会阻止准确报告 Docker 容器中 Java 进程消耗的内存。

这就是为什么像signalfx/docker-collectd-plugin 这样的插件在其PR -- Pull Request -- 35 中提到(两周前)“从内存使用百分比指标中扣除缓存数字”:

目前返回给 SignalFX 的容器/cgroup 的内存使用计算包括 Linux 页面缓存。
这通常被认为是不正确的,并且可能导致人们在他们的应用程序中追逐幻像内存泄漏。

为了演示当前计算不正确的原因,您可以运行以下命令来查看 I/O 使用情况如何影响 cgroup 中的整体内存使用情况:

docker run --rm -ti alpine
cat /sys/fs/cgroup/memory/memory.stat
cat /sys/fs/cgroup/memory/memory.usage_in_bytes
dd if=/dev/zero of=/tmp/myfile bs=1M count=100
cat /sys/fs/cgroup/memory/memory.stat
cat /sys/fs/cgroup/memory/memory.usage_in_bytes

您应该看到 usage_in_bytes 值仅在创建 100MB 文件后就增加了 100MB。该文件尚未被应用程序加载到匿名内存中,但由于它现在位于页面缓存中,因此容器内存使用率似乎更高。
从usage_in_bytes中减去memory.stat中的缓存数字,表明匿名内存的真正使用并没有上升。

signalFX 指标现在与您运行 docker stats 时看到的不同,后者使用了我在这里的计算。
似乎知道容器的页面缓存使用可能很有用(尽管我很难想到什么时候),但是知道它作为 cgroup 总体使用百分比的一部分是没有用的,因为它会伪装你的实际 RSS内存使用。
在最大堆大小与 cgroup 内存限制一样大或大于 cgroup 内存限制的垃圾收集应用程序中(例如,Java 的 -Xmx 参数或服务器模式下的 .NET 核心),百分比趋向于接近 100 % 然后只是悬停在那里,假设运行时可以正确看到 cgroup 内存限制。
如果您使用的是智能代理,我建议您使用docker-container-stats monitor(我将对其进行相同的修改以排除缓存内存)。

【讨论】:

  • 在内存消耗保持在 100% 时进行测试。我将 --memory 参数放入 docker run 命令。内存消耗徘徊在 100% 左右,但是我看到现在正在使用交换内存并且 CPU 平均负载有所增加。将应用程序移出容器是否是最好的选择?
【解决方案2】:

是的,NiFi docker 存在内存问题,一段时间后会出现问题并自行重新启动。另一方面,非码头工人工作得很好。

详情: 码头工人: 以 3gb 堆大小运行它,并在启动后立即消耗大约 2gb。运行一些处理器,机器的风扇运转得很厉害,一段时间后它会重新启动。

非 Docker: 以 3gb 堆大小运行它,它需要 900mb 并且运行平稳。 (jconsole)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-08
    • 2013-01-20
    • 2011-10-31
    • 2019-08-10
    • 2013-06-24
    • 2011-03-22
    相关资源
    最近更新 更多