【问题标题】:Apache NiFi - OutOfMemory Error: GC overhead limit exceeded on SplitText processorApache NiFi - OutOfMemory 错误:SplitText 处理器超出 GC 开销限制
【发布时间】:2016-12-03 20:55:07
【问题描述】:

我正在尝试使用 NiFi 使用 HDF 1.2 处理大型 CSV 文件(每个文件可能有数十亿条记录)。我已经实现了我的流程,对于小文件来说一切正常。

问题是,如果我尝试将文件大小推到 100MB(1M 记录),我会从负责将文件拆分为单个记录的 SplitText 处理器获得java.lang.OutOfMemoryError: GC overhead limit exceeded。我已经搜索过了,这基本上意味着垃圾收集器执行时间过长而没有获得太多堆空间。我预计这意味着生成太多流文件的速度太快。

我该如何解决这个问题?我尝试更改 nifi 关于最大堆空间和其他内存相关属性的配置,但似乎没有任何效果。

现在我添加了一个行数为 1K 的中间 SplitText,这可以让我避免错误,但我不认为这是一个可靠的解决方案,当传入的文件大小将可能远不止于此,恐怕我会从处理器中得到相同的行为。

欢迎任何建议!谢谢

【问题讨论】:

    标签: java garbage-collection hortonworks-data-platform apache-nifi hortonworks-sandbox


    【解决方案1】:

    错误的原因是当拆分 1M 行数为 1 的记录时,您正在创建等同于 1M Java 对象的 1M 流文件。总体而言,使用两个 SplitText 处理器的方法很常见,并且可以避免同时创建所有对象。您可能会在第一次拆分时使用更大的拆分大小,也许是 10k。对于十亿条记录,我想知道第三个级别是否有意义,从 1B 到可能 10M,然后从 10M 到 10K,然后从 10K 到 1,但我必须使用它。

    需要考虑的其他一些事情是从 512MB 增加默认堆大小,您可能已经这样做了,并且还要弄清楚您是否真的需要拆分为 1 行。如果不了解有关流程的任何其他信息,很难说,但在很多情况下,如果您想将每一行传递到某个地方,您可能会有一个处理器读取一个大的分隔文件并将每一行流式传输到目的地。例如,这就是 PutKafka 和 PutSplunk 的工作方式,它们可以获取一个 1M 行的文件并将每行流式传输到目标。

    【讨论】:

    • 如果没有“一次性”的方式来做到这一点,我肯定会尝试多个级别。关于 PutKafka,我最终会在集群中将 Kafka 和 NiFi 一起设置。忽略这将占用一些集群资源这一事实,从性能或其他角度来看是否有优势?一如既往地感谢您提供有关 NiFi 行为的有用信息。
    • 好吧,我并不是说您需要 Kafka 作为其中的一部分,我更多的是询问您将每个流文件拆分为 1 行后您想在流程中做什么,以查看如果你真的需要这样做。很多时候人们只是想将这些行传递到外部系统,在这些情况下,可能有一个处理器可以在大文件中流式传输并将每一行发送到某个地方,而无需创建数百万个流文件,kafka 和 splunk 是仅举两个例子。
    • 我实际上确实需要逐行拆分文件,然后对其每个字段应用不同的转换/规范化。然后我将每一行重新组合在一起并将所有内容都导出到 hive 上。
    • 只是想知道为什么将 10K 流文件的背压阈值放在成功队列上没有帮助?这将阻止 SplitText 处理器生成更多文件,并减少编号。 JVM中的对象。您甚至可以尝试使用 1K 阈值,具体取决于您的流量有多大。
    【解决方案2】:

    我在 Apache NiFi 中使用 GetMongo 处理器时遇到了类似的错误。 我将配置更改为:

    Limit: 100
    Batch Size: 10
    

    然后错误就消失了。

    【讨论】:

      猜你喜欢
      • 2017-11-12
      • 2021-03-14
      • 2016-05-25
      • 2010-11-26
      • 1970-01-01
      • 2018-04-10
      • 2021-01-07
      • 1970-01-01
      相关资源
      最近更新 更多