如何在CRON驱动的DetectDuplicate中摄取所有流文件?

时间:2018-04-12 12:14:18

标签: cron duplicates priority-queue apache-nifi

在NiFi中,我有一个由cron驱动的处理器序列,每天提供一组流程文件,其中包含我感兴趣的2个属性:product_codepublication_date

我的需要是每个product_code只保留一个流文件:具有最新publication_date的流文件。

例如:

对于此输入:

flow_1: product_code: A / publication_date : 2018-01-01
flow_2: product_code: B / publication_date : 2018-01-01
flow_3: product_code: C / publication_date : 2018-01-01
flow_4: product_code: A / publication_date : 2018-04-12
flow_5: product_code: A / publication_date : 2000-12-31
flow_6: product_code: B / publication_date : 2018-02-02
flow_7: product_code: B / publication_date : 2018-03-03

预期输出应为:

flow_3: product_code: C / publication_date : 2018-01-01
flow_4: product_code: A / publication_date : 2018-04-12
flow_7: product_code: B / publication_date : 2018-03-03

我测试的算法

  1. 使用UpdateAttribute处理器根据priority向每个流文件添加属性publication_date
  2. 这些更新的流文件被重定向到PriorityAttributePrioritizer队列。
  3. 流文件保留在此队列中,因为只有一个消耗处理器,它是由cron驱动的。通过这种方式,我确信队列中的流文件是根据publication_date排序的。
  4. 然后CRON根据DetectDuplicate属性触发下一个处理器product_code。由于流程文件是从最近的项目处理到最旧的项目,我确信当product_code被检测为重复时,这是因为相同的product_code已经可以使用更新的publication_date DetectDuplicate 1}}。
  5. 问题

    可悲的是,当cron触发DetectDuplicate处理器时,只消耗一条消息,其他消息留在队列中。

    如果我更改"计划策略"到"定时器驱动"使用"运行计划" 0,我的所有流量文件都被消耗,输出是预期的。

    有没有办法让我的DetectDuplicate处理器在它开始工作时消耗队列中的所有消息(而不仅仅是一条消息)?

    或者有没有办法建立一个类似于&#34的调度策略;开始在凌晨2:00工作,在凌晨4:00停止" ?

    您是否考虑过更好的策略来满足需求?

    此致

    缬氨酸。

    更新1

    (2018-04-13)更多信息,以及Bryan Bende的评论。

    我知道CRON不是最好的解决方案,但我不知道如何改进我的算法来摆脱它。

    在我的例子中,排队等待重复数据删除的flowFiles是通过一系列3个REST调用生成的:

    • 第一次致电" GetAllCategories",
    • 然后针对每个类别,调用" GetSubCategories",
    • 并为每个子类别调用" GetProducts"。

    此flowFiles生成部分通常持续约5分钟:昨晚第一个flowFile在凌晨2:00:16到达队列,最后一个在凌晨2:04:58到达队列。 (这就是为什么我安排DetectDuplicate在凌晨3:00运行的原因。)

    如果我的DetectDuplicate处理器是"定时器驱动"在所有flowFiles存在之前,处理器将消耗到达队列的第一个flowFiles。

    这会破坏整套flowFiles的排序。

    我觉得在{{1}}处理器开始工作之前我必须等待所有流文件进入队列。

    您是否有改进算法的潜在建议?

2 个答案:

答案 0 :(得分:4)

通常应该对启动流的源处理器使用CRON调度,然后所有其他处理器应该是定时器驱动的,运行时间表为0。

例如,如果您每天凌晨2:00从目录中选取文件,则应使用CRON表达式调度GetFile以在凌晨2:00启动流程,但除此之外的任何内容都不需要CRON调度,因为它们是除非GetFile运行,否则永远不会收到数据。

如果您希望处理器等待执行直到所有流文件都可用,您可以使用Wait / Notify处理器,这样所有流文件都会在Wait处理器之前构建,然后才会发布到DetectDuplicate处理器。

答案 1 :(得分:1)

只消耗一条消息的原因是当您在所有处理器中启用CRON调度时 - 源和消耗/下游处理器,它执行如下:

Ex:您已在所有处理器中设置CRON计划,以便每天下午2点运行,因此在触发期间,它将使用来自其上游处理器的一个流文件:GetFile在下午2点,其余的流文件将在队列中,下一个流文件将仅在第二天下午2点消耗,依此类推。这适用于更进一步的下游处理器,这意味着它们也将在每天下午2点一次仅消耗流文件,这实际上是一个灾难。谁希望处理速度达到蜗牛的速度?

这就是为什么你必须遵循@Bryan提到的方法。流管道应仅将其源处理器设为CRON driven,其余处理器应为Timer driven,并且具有您希望的运行计划,但通常0 sec用于将流文件用作它来了。