我已经完成了Hazelcast Jet的工作,该任务将IoT测量流转换为警报流。
因此,只要一个传感器的湿度水平超过阈值,就会发出警报。当它再次降至阈值以下时,警报将被清除。阈值(严重性)最多可以达到3个级别。
当前,我在开始工作时遇到问题。它将从RabbitMQ源中清除所有缓冲的事件。因此,远事件是有序的,因为局部并行性是一个(这里假设单个成员集群)。但是我们将事件分派到合作线程池中,订单上没有担保。我可以指示Jet按顺序处理具有相同传感器ID的所有事件吗?
这是我的管道的当前定义:
StreamStage<Notification> ss = l
.drawFrom(
Sources.<SimpleEntry<String, String>> streamFromProcessor("rabbitmq", ReadRabbitMQP.readRabbitMQ()))
.map(e -> makeMeasurement(e))
.flatMap(e -> checkThresholds(e))
.flatMap(e -> checkNotification(e));
ss.drainTo(Sinks.logger());
checkNotification将事件的严重性与该传感器的最新严重性进行比较。这就是为什么顺序很重要的原因。
我试图实施Gokhan Oner建议的解决方案: 我修改了源代码以输出SimpleMeasurement对象。这样,我可以在源之后添加时间戳。
StreamStage<Notification> ss = l
.drawFrom(Sources.<SimpleEntry<Integer, SimpleMeasurement>> streamFromProcessor("rabbitmq",
ReadRabbitMQP.readRabbitMQ(mGroupNames, mLocalParallelism)))
.addTimestamps(e -> e.getValue().getTimestamp().toEpochMilli(), 1000)
.flatMap(e -> checkThresholds(e))
.groupingKey(e -> e.getSensorId())
.window(WindowDefinition.tumbling(1))
.aggregate(AggregateOperations.sorting(DistributedComparator.comparing(e -> e.getPeakTime())))
.flatMap(e -> checkNotification(e));
ss.drainTo(Sinks.logger());
使用此代码,仍然不会为相同的传感器ID处理事件。此外,从从事件源读取事件到在“ checkNotification”中对其进行处理之间还有20秒的延迟。
答案 0 :(得分:1)
@ PeeWee2201,因为这是分布式流,所以没有保证的顺序。但是,如果要按顺序处理来自相同传感器的通知,则需要:
所以工作应该像这样:
StreamStage<Notification> ss = l
.drawFrom(
Sources.<SimpleEntry<String, String>> streamFromProcessor("rabbitmq", ReadRabbitMQP.readRabbitMQ()))
.addTimestamps(...., ...)
.groupingKey(....)
.window(WindowDefinition.tumbling(....))
.aggregate(AggregateOperations.sorting(....))
如果makeMeasurement(e)
是转换数据的步骤并且可以并行运行,则可以在分组之前添加它。
此后,您将获得checkThresholds
方法的对象列表:窗口中针对同一sensorId的所有消息,这些消息按到达时间或您使用的任何排序顺序排序。
我相信这将有助于解决您的问题。