Flink滑动窗口查询SWQ=f,l,p参数的实现代码求助
Flink滑动窗口查询(SWQ)功能实现代码示例
你提到的SWQ三元组参数和Flink侧组件的映射如下:
f:窗口触发频率,对应Flink计数滑动窗口的滑动步长,每收到f个事件就触发一次窗口计算l:滑动窗口长度,对应Flink计数滑动窗口的窗口大小,每个窗口包含最近l个事件p:目标事件模式,对应Flink CEP库的Pattern规则,用于匹配窗口内的特定事件组合
以下为Flink 1.17+版本的Java实现示例:
核心依赖(Maven配置)
<dependency> <groupId>org.apache.flink</groupId> <artifactId>flink-streaming-java</artifactId> <version>1.17.1</version> </dependency> <dependency> <groupId>org.apache.flink</groupId> <artifactId>flink-cep</artifactId> <version>1.17.1</version> </dependency>
业务实现代码
import org.apache.flink.cep.CEP; import org.apache.flink.cep.PatternSelectFunction; import org.apache.flink.cep.pattern.Pattern; import org.apache.flink.cep.pattern.conditions.SimpleCondition; import org.apache.flink.streaming.api.datastream.DataStream; import org.apache.flink.streaming.api.environment.StreamExecutionEnvironment; import org.apache.flink.streaming.api.functions.windowing.AllWindowFunction; import org.apache.flink.streaming.api.windowing.windows.GlobalWindow; import org.apache.flink.util.Collector; // 自定义事件类,可根据业务调整字段 class Event { public String eventType; public long timestamp; public Event() {} public Event(String eventType, long timestamp) { this.eventType = eventType; this.timestamp = timestamp; } } public class SWQJob { public static void main(String[] args) throws Exception { final StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment(); // -------------------------- 配置SWQ参数 -------------------------- final int f = 10; // 每10个事件触发一次查询 final int l = 50; // 窗口长度为50个事件 // 定义模式p:连续3个不同类型的事件,可根据业务需求调整规则 Pattern<Event, ?> p = Pattern.<Event>begin("first") .where(new SimpleCondition<Event>() { @Override public boolean filter(Event event) { return event.eventType != null; } }) .next("second") .where(new SimpleCondition<Event>() { @Override public boolean filter(Event event) { Event first = getPatternContext().getEventsForPattern("first").get(0); return !event.eventType.equals(first.eventType); } }) .next("third") .where(new SimpleCondition<Event>() { @Override public boolean filter(Event event) { Event first = getPatternContext().getEventsForPattern("first").get(0); Event second = getPatternContext().getEventsForPattern("second").get(0); return !event.eventType.equals(first.eventType) && !event.eventType.equals(second.eventType); } }); // -------------------------- 业务逻辑实现 -------------------------- // 接入事件流,示例用socket作为源,可替换为Kafka等实际数据源 DataStream<Event> inputStream = env.socketTextStream("localhost", 9999) .map(text -> { String[] parts = text.split(","); return new Event(parts[0], Long.parseLong(parts[1])); }); // 配置滑动计数窗口,窗口大小l,滑动步长f DataStream<Event> windowedStream = inputStream .countWindowAll(l, f) .apply(new AllWindowFunction<Event, Event, GlobalWindow>() { @Override public void apply(GlobalWindow window, Iterable<Event> events, Collector<Event> out) { for (Event event : events) { out.collect(event); } } }); // 在窗口流上匹配目标模式p CEP.pattern(windowedStream, p) .select(new PatternSelectFunction<Event, String>() { @Override public String select(java.util.Map<String, java.util.List<Event>> pattern) { Event first = pattern.get("first").get(0); Event second = pattern.get("second").get(0); Event third = pattern.get("third").get(0); return "匹配到目标模式:事件类型依次为" + first.eventType + "->" + second.eventType + "->" + third.eventType; } }) .print(); env.execute("滑动窗口查询SWQ任务"); } }
如果需要使用事件时间语义,将计数窗口替换为事件时间滑动窗口,同时配置水位线生成规则即可;模式p的规则可根据业务需求灵活调整,支持连续匹配、可选匹配、时间限制等多种规则。
内容的提问来源于stack exchange,提问作者AHMAD SALEEM MIRZA
相关产品推荐
相关产品推荐

