前情提要: 最近阅读《Flink实战派》这本书学习Flink,但是这本书基本上就是整理、翻译了Flink上面的文档,几乎没有什么入门价值,然而Flink文档这块写的也不是很好,网上基本上又都是二手贩子,复制粘贴的,所以自己动手吧。
国际惯例,先放引用方法与源码地址:
<!-- pom.xml -->
<dependency>
<groupId>org.apache.flink</groupId>
<artifactId>flink-cep_2.11</artifactId>
<version>1.13.6</version>
</dependency>
<dependency>
<groupId>org.apache.flink</groupId>
<artifactId>flink-cep-scala_2.11</artifactId>
<version>1.13.6</version>
</dependency>
源码位于flinkGithub的flink-libraries/目录下,分为flink-cep和 flink-cep-scala两个分支。
考虑到flink上面去scala化是未来大趋势,所以本文选取java版本来讲解。
了解一个东西,最好的方法是从定义开始:
官方定义:
FlinkCEP is the Complex Event Processing (CEP) library implemented on top of Flink. It allows you to detect event patterns in an endless stream of events, giving you the opportunity to get hold of what’s important in your data.
The events in the DataStream to which you want to apply pattern matching must implement proper equals() and hashCode() methods because FlinkCEP uses them for comparing and matching events.
分析:
- FlinkCEP不是Flink-dist的一部分,是基于Flink实现的,因此需要单独饮用。
- FlinkCEP的作用是在无界数据流(因此只能应用于DataStream)中执行模式匹配
- 因为要执行模式匹配,所以事件类必须实现用来比较和比对的equals()和hashCode()方法
先放一段官方给出的“意义不明”的示范代码:
DataStream<Event> input = ...
Pattern<Event, ?> pattern = Pattern.<Event>begin("start").where(
new SimpleCondition<Event>() {
@Override
public boolean filter(Event event) {
return event.getId() == 42;
}
}
).next("middle").subtype(SubEvent.class).where(
new SimpleCondition<SubEvent>() {
@Override
public boolean filter(SubEvent subEvent) {
return subEvent.getVolume() >= 10.0;
}
}
).followedBy("end").where(
new SimpleCondition<Event>() {
@Override
public boolean filter(Event event) {
return event.getName().equals("end");
}
}
);
PatternStream<Event> patternStream = CEP.pattern(input, pattern);
DataStream<Alert> result = patternStream.process(
new PatternProcessFunction<Event, Alert>() {
@Override
public void processMatch(
Map<String, List<Event>> pattern,
Context ctx,
Collector<Alert> out) throws Exception {
out.collect(createAlertFrom(pattern));
}
});
看完之后,我有许多疑问:
- 是否第一个事件必须起名为start?
- next和followedBy是否存在意义上的先后顺序?
- 这种调用方式看起来很恶心,我能不能先把每个事件建立好,然后建立连接关系呢?
通过阅读源码,我们必须要一一回答这些问题!
Pattern、模式,作为模式匹配的基本单位,分为个体模式 Individual Pattern 和 组合模式 Combining Pattern两种。个体模式通过调用next、followedby 等意义不明的函数来组合,建立顺序关系。作者本身比较讨厌这种文档,因为在中文语境里,先说next、还是先说followedby等词语,是意义不明的。因此,我们直接阅读源代码。
如何定义
我们打开org.apache.flink.cep.pattern.Pattern类的源代码,找到定义方法:
protected Pattern(
final String name,
final Pattern<T, ? extends T> previous,
final ConsumingStrategy consumingStrategy,
final AfterMatchSkipStrategy afterMatchSkipStrategy) {
this.name = name;
this.previous = previous;
this.quantifier = Quantifier.one(consumingStrategy);
this.afterMatchSkipStrategy = afterMatchSkipStrategy;
}
FlinkCEP库不允许直接以new的形式定义,属于设计模式的一种,意义在于,必须通过指定的static 方法来创建对

最低0.47元/天 解锁文章
1528

被折叠的 条评论
为什么被折叠?



