簡體   English   中英

Apache Flink CEP如何檢測事件是否在x秒內未發生?

[英]Apache Flink CEP how to detect if event did not occur within x seconds?

例如,A應該在10秒之內跟隨B。 我知道如何跟蹤此DID是否發生(.next,.within),但是如果B從未在窗口內發生,我想發送警報。

    public static void main(String[] args) throws Exception {
        final StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();

        // checkpointing is required for exactly-once or at-least-once guarantees
//      env.enableCheckpointing(1000);

        final RMQConnectionConfig connectionConfig = new RMQConnectionConfig.Builder()
            .setHost("localhost")
            .setPort(5672)
            .setVirtualHost("/")
            .setUserName("guest")
            .setPassword("guest")
            .build();

        final DataStream<String> inputStream = env
            .addSource(new RMQSource<String>(
                connectionConfig,               // config for the RabbitMQ connection
                "cep",                          // name of the RabbitMQ queue to consume
                true,                           // use correlation ids; can be false if only at-least-once is required
                new SimpleStringSchema()))      // deserialization schema to turn messages into Java objects
            .setParallelism(1);                 // non-parallel source is only required for exactly-once

        inputStream.print();

        Pattern<String, ?> simplePattern =
                Pattern.<String>begin("start")
                    .where(new SimpleCondition<String>() {
                        @Override
                        public boolean filter(String event) {
                            return event.equals("A");
                        }
                    })
                    .next("end")
                    .where(new SimpleCondition<String>() {
                        @Override
                        public boolean filter(String event) {
                            return event.equals("B");
                        }
                    });

        PatternStream<String> timedOutPatternStream = CEP.pattern(inputStream, simplePattern.within(Time.seconds(10)));
        OutputTag<String> timedout = new OutputTag<String>("timedout"){};
        SingleOutputStreamOperator<String> timedOutNotificationsStream = timedOutPatternStream.flatSelect(
            timedout,
            new TimedOut<String>(),
            new FlatSelectNothing<String>()
        );
        timedOutNotificationsStream.getSideOutput(timedout).print();

        env.execute("mynotification");
    }

public static class TimedOut<String> implements PatternFlatTimeoutFunction<String, String> {
    @Override
    public void timeout(Map<java.lang.String, List<String>> pattern, long timeoutTimestamp, Collector<String> out) throws Exception {
        out.collect((String) "LATE!");
    }
}

public static class FlatSelectNothing<T> implements PatternFlatSelectFunction<T, T> {
    @Override
    public void flatSelect(Map<String, List<T>> pattern, Collector<T> collector) {}
}

實際行為:

publish "A"
(wait 5 seconds)
publish "B"
=> (no alert)

publish "A"
(wait 10 seconds)
=> (no alert, but should be)

publish "A"
(wait 10 seconds)
publish "B"
=> "LATE!"

預期行為:

publish "A"
(wait 10 seconds)
=> "LATE!"

您可以通過超時模式進行操作。 您可以A followedBy B within 10 seconds指定類似A followedBy B within 10 seconds模式, A followedBy B within 10 seconds並檢查超時的模式,這意味着只有A。 您可以在此處檢查文檔中的超時模式

對於一個完整的例子,你可以參考這個培訓或直接到解決鍛煉; Tibial


編輯:現在(flink <1.5)處理時間修剪僅在傳入元素上完成。 因此,不幸的是,在超時之后,必須至少有一個事件(觸發與否無關)將觸發超時。 可以使用這張吉拉來跟蹤改進的努力

您可以嘗試以下解決方案嗎?

package com.nirav.modi.cep;

import com.nirav.modi.dto.Event;
import org.apache.flink.cep.CEP;
import org.apache.flink.cep.PatternFlatSelectFunction;
import org.apache.flink.cep.PatternFlatTimeoutFunction;
import org.apache.flink.cep.PatternStream;
import org.apache.flink.cep.pattern.Pattern;
import org.apache.flink.cep.pattern.conditions.SimpleCondition;
import org.apache.flink.streaming.api.datastream.DataStreamSource;
import org.apache.flink.streaming.api.datastream.SingleOutputStreamOperator;
import org.apache.flink.streaming.api.environment.StreamExecutionEnvironment;
import org.apache.flink.streaming.api.functions.source.SourceFunction;
import org.apache.flink.streaming.api.windowing.time.Time;
import org.apache.flink.util.Collector;
import org.apache.flink.util.OutputTag;

import java.util.List;
import java.util.Map;

public class EventNotOccur {

    public static void main(String[] args) throws Exception {
        StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();

        DataStreamSource<Event> source = env.addSource(new SourceFunction<Event>() {
            @Override
            public void run(SourceContext<Event> ctx) throws Exception {

                for (int i = 0; i < 1; i++) {
                    ctx.collect(new Event("A"));
                    Thread.sleep(5000);
                    ctx.collect(new Event("B"));
                    Thread.sleep(5000);
                    ctx.collect(new Event("A"));
                    Thread.sleep(15000);
                    ctx.collect(new Event("B"));
                    Thread.sleep(5000);
                    ctx.collect(new Event("B"));
                }
            }

            @Override
            public void cancel() {

            }
        });

        Pattern<Event, ?> simplePattern =
                Pattern.<Event>begin("start")
                        .where(new SimpleCondition<Event>() {
                            @Override
                            public boolean filter(Event event) {
                                return event.getName().equals("A");
                            }
                        })
                        .next("end")
                        .where(new SimpleCondition<Event>() {
                            @Override
                            public boolean filter(Event event) {
                                return event.getName().equals("B");
                            }
                        });

        source.print();

        PatternStream<Event> timedOutPatternStream = CEP.pattern(source, simplePattern.within(Time.seconds(10)));

        OutputTag<Event> timedout = new OutputTag<Event>("timedout") {

        };

        timedOutPatternStream.flatSelect(new PatternFlatSelectFunction<Event, String>() {
            @Override
            public void flatSelect(Map<String, List<Event>> pattern, Collector<String> out) throws Exception {
                out.collect("Pattern Match...............");
            }
        }).print();

        SingleOutputStreamOperator<Event> longRides = timedOutPatternStream
                .flatSelect(
                        timedout,
                        new EventTimeOut(),
                        new FlatSelectNothing()
                );

        longRides.getSideOutput(timedout).print();


        env.execute("Flink Streaming Java API Skeleton");

    }

    public static class EventTimeOut<Event> implements PatternFlatTimeoutFunction<Event, Event> {
        @Override
        public void timeout(Map<String, List<Event>> map, long l, Collector<Event> collector) throws Exception {
            Event rideStarted = map.get("start").get(0);
            System.out.println("Time out Partial Event : " + rideStarted);
            collector.collect(rideStarted);
        }
    }

    public static class FlatSelectNothing<T> implements PatternFlatSelectFunction<T, T> {
        @Override
        public void flatSelect(Map<String, List<T>> pattern, Collector<T> collector) {

            System.out.println("Flat select nothing: " + pattern.get("start").get(0));
            collector.collect(pattern.get("start").get(0));

        }
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM