记录Flink CEP的Pattern没有被触发的问题(Table SQL处理后水位线丢失)

1,301 阅读1分钟

1.记录Flink CEP的Pattern没有被触发的问题

1.1.问题描述

1:我设置了Watermark(水位线)使用事件时间

2:然后使用StreamTableEnvironment注册了View,使用SQL做聚合计算

3:然后将表转换为流

4:然后定义Flink CEP 的Pattern对得到的数据流做规则匹配

5:结果是CEP没有被触发 代码如下:

//实时数据流
DataStreamSource<String> dataSource = env.addSource(kafkaConsumer);

//将数据流映射为数据实体
DataStream<CleanBean> cleanBeanDataStream = dataSource.map(new CleanBeanMap());

//设置水位线
DataStream<CleanBean> waterData = cleanBeanDataStream
        .assignTimestampsAndWatermarks(
                WatermarkStrategy.
                        <CleanBean>forBoundedOutOfOrderness(Duration.ofSeconds(/*Long.valueOf(ProjectConfig.config.getProperty("delay.time"))*/0))
                        .withTimestampAssigner((cleanBean, l) -> (cleanBean.getEventTime()))
        );

//注册表(流)
StreamTableEnvironment tEnv = StreamTableEnvironment.create(env);
tEnv.createTemporaryView("TableDemo", mapData, $("tableName"), $("fDouble"), $("fLong"), $("fString"), $("fBoolean"), $("eventTime").rowtime());

//执行查询
Table table = tEnv.sqlQuery("select tableName,avg(fDouble) as temperature from TableDemo group by tableName, TUMBLE(eventTime,INTERVAL '2' SECOND)");

//表转流
DataStream<WarnTemperatureBean> streamData = tEnv.toAppendStream(table, WarnTemperatureBean.class);

//定义模式匹配规则
Pattern<WarnTemperatureBean, WarnTemperatureBean> pattern = Pattern.<WarnTemperatureBean>begin("start").where(new SimpleCondition<WarnTemperatureBean>() {
            @Override
            public boolean filter(WarnTemperatureBean value) throws Exception {
                return true;
            }
});        

//把模式匹配作用到数据流中
CEP.pattern(streamData.keyBy(WarnTemperatureBean::getTableName), pattern)
                .select(new PatternSelectFunction<WarnTemperatureBean, Object>() {
                    @Override
                    public Object select(Map<String, List<WarnTemperatureBean>> map) throws Exception {
                        List<WarnTemperatureBean> next = map.get("next");
                        if (next != null && next.size() > 0) {
                            //发送告警邮件
                            System.out.println("告警数据:"+next);
                        }
                        return next;
                    }
                }).print("===========规则匹配提取数据===========》");

1.2.解决方法

需要重新设置水位线。重设水位线之后即可触发CEP。

目前怀疑经过Flink SQL处理后得到Table,然后转换为Stream会将水位线丢失。

各位大侠有自己的看法欢迎讨论。