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会将水位线丢失。
各位大侠有自己的看法欢迎讨论。