我想知道在Apache Storm中解决以下问题的最佳做法是什么。
我有一个spout,它生成一个带有显式时间戳的整数值流。目标是在此流上使用三个滑动窗口执行最小/最大聚合:
最后一小时很简单:
topology.setBolt("1h", ...)
.shuffleGrouping("spout")
.withWindow(Duration.hours(1), Duration.seconds(10))
.withTimestampField("timestamp"));
但是,在较长时间内,我担心窗口的队列大小。当我使用最后一小时聚合直接从spout消耗元组时,每个元组都会在队列中结束。
一种可能性是从预先聚合的“1h”螺栓中消耗元组。但是,由于我使用的是显式时间戳,因此忽略从“1h”螺栓到达的后期元组。 1小时滞后不是一个选项,因为这会延迟窗口的评估。有没有办法在不影响结果及时性的情况下“允许”后期元组?
当然,我还可以每小时存储一次聚合,然后计算过去24小时内的最小值,包括“1h”流中的最新值。但我很好奇是否有办法使用Storm手段正确地做到这一点。
感谢arunmahadevan的回答,我改变了1h min螺栓,发出了最小元组,其中包含了相应1h窗口中所有元组的最大时间戳。这样消耗螺栓不会因迟到而丢弃元组。我还引入了一个新字段original-timestamp
来保留最小元组的原始时间戳。
我终于通过仅在1h min螺栓中发出状态变化找到了更好的方法。只要没有收到新的元组,Storm就不会延长消耗螺栓的时间,因此可以防止延迟到达问题。此外,我保留原始时间戳,而不将其复制到单独的字段中。
答案 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。