风暴:几个不同大小的滑动窗口的最小/最大聚合

时间:2017-05-04 16:32:34

标签: apache-storm

我想知道在Apache Storm中解决以下问题的最佳做法是什么。

我有一个spout,它生成一个带有显式时间戳的整数值流。目标是在此流上使用三个滑动窗口执行最小/最大聚合:

  • 最后一小时
  • 最后一天,即过去24小时

最后一小时很简单:

topology.setBolt("1h", ...)
    .shuffleGrouping("spout")
    .withWindow(Duration.hours(1), Duration.seconds(10))
    .withTimestampField("timestamp"));

但是,在较长时间内,我担心窗口的队列大小。当我使用最后一小时聚合直接从spout消耗元组时,每个元组都会在队列中结束。

一种可能性是从预先聚合的“1h”螺栓中消耗元组。但是,由于我使用的是显式时间戳,因此忽略从“1h”螺栓到达的后期元组。 1小时滞后不是一个选项,因为这会延迟窗口的评估。有没有办法在不影响结果及时性的情况下“允许”后期元组?

当然,我还可以每小时存储一次聚合,然后计算过去24小时内的最小值,包括“1h”流中的最新值。但我很好奇是否有办法使用Storm手段正确地做到这一点。

更新1

感谢arunmahadevan的回答,我改变了1h min螺栓,发出了最小元组,其中包含了相应1h窗口中所有元组的最大时间戳。这样消耗螺栓不会因迟到而丢弃元组。我还引入了一个新字段original-timestamp来保留最小元组的原始时间戳。

更新2

我终于通过仅在1h min螺栓中发出状态变化找到了更好的方法。只要没有收到新的元组,Storm就不会延长消耗螺栓的时间,因此可以防止延迟到达问题。此外,我保留原始时间戳,而不将其复制到单独的字段中。

1 个答案:

答案 0 :(得分:0)

我认为定期从“1h”到“24h”螺栓发射最小值应该可以正常工作并保持“24h”队列大小。

如果配置滞后,则仅在该滞后之后(即当事件时间越过滑动间隔+滞后时)调用螺栓的执行。

假设如果“1h”螺栓配置了1分钟的延迟,则只有在事件时间超过02:01后才会在01:00 - 02:00之间为元组调用执行。 (即螺栓已经看到时间戳> = 02:01的事件)。但是,execute只会在01:00到02:00之间收到元组。

现在,如果计算最后一小时最小值并将结果发送到滑动间隔为1小时且滞后= 0的“24小时”螺栓,则一旦传入事件的时间戳超过下一小时,它将触发。如果您以02:00的时间戳发出01:00-02:00分钟,则一旦收到最小事件,“24h”窗口将触发(前一天02:00至02:00之间的事件)因为事件时间超过了下一个小时,配置的延迟为0。