在流数据上运行多个用例

时间:2020-05-25 10:25:29

标签: apache-flink flink-streaming

我正在从Kafka获取流式传感器数据,我需要执行以下操作:

a。检查一个时间段内变量的变化,如果过大则发出警报(例如5分钟内温度从非常低到非常高的变化)。我检查我是否有一个非常低的温度,设置5分钟的计时器,观察我是否在5分钟内有一个非常高的温度,如果是,我会发出警报

b。另外,如果我的温度很高,那么我会在5分钟的窗口中检查是否有非常低的温度

c。每1分钟计算一次温度的运行平均值,然后推至kafka。这是一项连续的活动,从一开始我需要一个计时器,每1分钟递增运行一次

我无法理解如何在同一代码中为所有这些用例使用计时器。任何建议。

2 个答案:

答案 0 :(得分:1)

Flink的滚动时间窗口与情况c很好匹配,但与情况a和b不太匹配。这是因为这些窗口无法与触发事件对齐-而是始终与时钟对齐(例如,从12:00到12:05)。因此,如果高温事件在12:04发生,然后在12:06下降很多,则这两个事件将在不同的窗口中。

对于a和b,我建议使用DataStream API中的interval join,或者使用TableSQL API进行时间窗联接。像

SELECT *
FROM events e1, events e2
WHERE e1.id = e2.id AND
      e2.time BETWEEN e1.time AND e1.time + INTERVAL '5' MINUTE AND
      ABS(e1.temp - e2.temp) > 50

如果您确实必须将这三种情况结合在一起,那么我建议使用KeyedProcessFunction,但这会变得更加困难,特别是如果您需要担心事件无序到达时。而且,由于一分钟的时间间隔与五分钟的时间间隔不同步,因此您将需要多个计时器。

答案 1 :(得分:0)

因此Flink具有Windows Read More Here的概念。

还有一个键控和非键控流的概念,如果您想在处理Read more Here之前隔离数据,这也将为您提供帮助。

  • 对于a&b->我建议您使用5分钟的简单TumblingEventTimeWindows间隔,并以process方法编写自定义逻辑。因此,我相信每5分钟就会一起处理元素,这是我最终想要做的事情。
  • 对于c->我再次建议使用1分钟的简单TumblingEventTimeWindows并使用reduce方法计算平均温度

下面的代码假定流是non-keyed且具有ProcessingTime TimeCharacteristic。


        // By Default TimeCharacteristic is ProcessingTime
        env.setStreamTimeCharacteristic(TimeCharacteristic.ProcessingTime);

        // for a & b 
        data
                .windowAll(TumblingEventTimeWindows.of(Time.minutes(5)))
                .process(new ProcessAllWindowFunction<String, String, TimeWindow>() {
                    @Override
                    public void process(Context context, Iterable<String> iterable, Collector<String> collector) throws Exception {
                        for(String elements: iterable){
                            // custom logic here

                                ....
                            // collect your result
                            collector.collect(elements);
                        }
                    }
                })
                .addSink(Push it to whatever Sink);

        // For c
        data
                .windowAll(TumblingEventTimeWindows.of(Time.minutes(1)))
                .reduce(new ReduceFunction<String>() {
                    @Override
                    public String reduce(String s, String t1) throws Exception {
                        // Calculate Avg
                        return avg;
                    }
                })
                // Add to Kafka
                .addSink(new FlinkKafkaProducer<>(topic,new SimpleStringSchema,kafkaProperties);