JVM 运行 nifi 内存不足异常

JVM running out of memory exception in nifi

我不能使用任何处理器,因为它会抛出异常,当我想清除连接队列时,它会抛出异常,例如 this:0 FlowFiles(0 字节)已从队列中删除。

由于java.lang.IllegalStateException无法删除 FlowFiles:无法更新存储库,因为此时所有分区都不可用。写入存储库会导致损坏。这通常是由于存储库 运行 磁盘 space 或 JVM 运行 内存不足造成的。

在这种情况下,听起来好像您的磁盘已满。您可以使用 bootstrap.conf.

中的 Java args 增加分配给 JVM 运行 Apache NiFi 的堆数量
# JVM memory settings
java.arg.2=-Xms4096m
java.arg.3=-Xmx8192m 

通常建议将 content repository, provenance repository, and flowfile repository 保存在不同的磁盘上,并为每个磁盘分配适当的存储空间。您可以为 nifi.properties 中的每个配置最大大小,以使它们更快地老化数据。

NiFi 与 FlowFiles 配合使用。存在的每个 FlowFile 都由两部分组成,FlowFile 内容和 FlowFile 属性。虽然 FlowFile 的内容存在于内容存储库的磁盘上,但 NiFi 在配置的 JVM 堆内存 space 中保留了 FlowFile 属性数据的“大部分”。我说“多数”是因为 NiFi 会在包含超过 20,000 个 FlowFiles 的任何队列上将属性交换到磁盘(默认,但可以在 nifi.properties 中更改)。

一旦您的 NiFi 报告 OutOfMemory (OOM) 错误,除了重启 NiFi 之外没有任何纠正措施。如果不对您的 NiFi 或数据流进行更改,您肯定会一次又一次地遇到这个问题。

NiFi 中 JVM 堆的默认配置仅为 512 MB。这个值在nifi-bootstrap.conf文件中设置。

# JVM memory settings
java.arg.2=-Xms3072m
java.arg.3=-Xmx8096m

NiFi 已经有一个内置机制来帮助减少整体堆占用空间。当给定连接的队列超过配置的阈值时,该机制将 FlowFiles 属性交换到磁盘。这些设置可在 nifi.properties 文件中找到:

nifi.swap.manager.implementation=org.apache.nifi.controller.FileSystemSwapManager
nifi.queue.swap.threshold=20000
nifi.swap.in.period=5 sec
nifi.swap.in.threads=1
nifi.swap.out.period=5 sec
nifi.swap.out.threads=4

运行堆内存不足的一些常见原因包括:

  1. 大容量数据流,在您的数据流中任何给定时间都有大量 FlowFiles 处于活动状态。 (在 bootstrap.conf 中增加已配置的 nifi 堆大小以解决)

  2. 在每个 FlowFile 上创建大量属性。更多属性等于每个 FlowFile 的更多堆使用。避免在 FlowFiles 上创建 unused/unnecessary 属性。 (增加 bootstrap.conf 中配置的 nifi 堆大小以解决 and/or 降低配置的交换阈值)

  3. 正在将大值写入 FlowFile 属性。提取大量内容并将其写入 FlowFile 上的属性将导致高堆使用率。尽可能避免创建大型属性。 (增加 bootstrap.conf 中配置的 nifi 堆大小以解决 and/or 降低配置的交换阈值)

  4. 使用 MergeContent 处理器合并大量的 FlowFile。 NiFi 不能合并交换的 FlowFiles,所以当合并发生时,所有这些 FlowFile 的属性必须在堆中。如果需要合并大量的 FlowFiles,请尝试使用两个串联的 MergeContent 处理器。首先合并最多 20,000 个 FlowFiles,然后将这 10,000 个 FlowFile 文件合并到更大的包中。 (在 bootstrap.conf 中增加已配置的 nifi 堆大小也有帮助)

  5. 使用 SplitText 处理器将一个文件拆分成大量的 FlowFile。在队列超过交换阈值之前,不会发生大连接队列的交换。 SplitTEXT 处理器将创建所有拆分的 FiLowFiles,然后再将它们提交给成功关系。当 SpitText 用于按每一行拆分大型传入 FlowFile 时最常见。在创建所有拆分之前,可能 运行 超出堆内存。尝试串联使用两个 SplitText 处理器。第一个将传入的 FlowFiles 分成大块,第二个将它们进一步拆分。 (在 bootstrap.conf 中增加已配置的 nifi 堆大小也有帮助)

来源:https://community.cloudera.com/t5/Community-Articles/How-to-address-JVM-OutOfMemory-errors-in-NiFi/ta-p/244431