|NO.Z.00056|——————————|BigDataEnd|——|Hadoop&Flink.V11|——|Flink.v11|Flink CEP|Flink CEP基础|个体模式|模式序列|模式检测|匹配事件提取|超时事件提取|
一、Pattern API
### --- PatternAPI
~~~ 处理事件的规则,被叫作模式(Pattern)。
~~~ Flink CEP提供了Pattern API用于对输入流数据进行复杂事件规则定义,
~~~ 用来提取符合规则的事件序列。
二、模式大致分为三类:
### --- 个体模式(Individual Patterns)
~~~ 组成复杂规则的每一个单独的模式定义,就是个体模式。
start.times(3).where(_.behavior.startsWith(‘fav’))
### --- 组合模式(Combining Patterns,也叫模式序列)
~~~ 很多个体模式组合起来,就形成了整个的模式序列。
~~~ 模式序列必须以一个初始模式开始:
val start = Pattern.begin(‘start’)
### --- 模式组(Group of Pattern)
~~~ 将一个模式序列作为条件嵌套在个体模式里,成为一组模式。
三、模式说明
### --- 个体模式
~~~ 个体模式包括单例模式和循环模式。单例模式只接收一个事件,而循环模式可以接收多个事件。
~~~ # 量词
~~~ 可以在一个个体模式后追加量词,也就是指定循环次数。
~~~ # 匹配出现4次
start.time(4)
~~~ # 匹配出现0次或4次
start.time(4).optional
~~~ # 匹配出现2、3或4次
start.time(2,4)
~~~ # 匹配出现2、3或4次,并且尽可能多地重复匹配
start.time(2,4).greedy
~~~ # 匹配出现1次或多次
start.oneOrMore
~~~ # 匹配出现0、2或多次,并且尽可能多地重复匹配
start.timesOrMore(2).optional.greedy
### --- 条件
~~~ 每个模式都需要指定触发条件,作为模式是否接受事件进入的判断依据。
~~~ CEP中的个体模式主要通过调用.where()、.or()和.until()来指定条件。
### --- 按不同的调用方式,可以分成以下几类:
~~~ # 简单条件
~~~ 通过.where()方法对事件中的字段进行判断筛选,决定是否接收该事件
start.where(event=>event.getName.startsWith(“foo”))
~~~ # 组合条件
~~~ 将简单的条件进行合并;or()方法表示或逻辑相连,where的直接组合就相当于与and。
Pattern.where(event => …/*some condition*/).or(event => /*or condition*/)
~~~ # 终止条件
~~~ 如果使用了oneOrMore或者oneOrMore.optional,建议使用.until()作为终止条件,以便清理状态。
~~~ # 迭代条件
~~~ 能够对模式之前所有接收的事件进行处理;调用.where((value,ctx) => {…}),
~~~ 可以调用ctx.getEventForPattern(“name”)
二、模式序列
### --- 不同的近邻模式如下图:
~~~ # 严格近邻
~~~ 所有事件按照严格的顺序出现,中间没有任何不匹配的事件,由.next()指定。
~~~ 例如对于模式“a nextb”,事件序列“a,c,b1,b2”没有匹配。
~~~ # 宽松近邻
~~~ 允许中间出现不匹配的事件,由.followedBy()指定。例如对于模式“a followedBy b”,
~~~ 事件序列“a,c,b1,b2”匹配为{a,b1}。

~~~ # 非确定性宽松近邻
~~~ 进一步放宽条件,之前已经匹配过的事件也可以再次使用,由.followedByAny()指定。
~~~ 例如对于模式“a followedByAny b”,事件序列“a,c,b1,b2”匹配为{ab1},{a,b2}。
~~~ 除了以上模式序列外,
~~~ # 还可以定义“不希望出现某种近邻关系”:
~~~ .notNext():不想让某个事件严格紧邻前一个事件发生。
~~~ .notFollowedBy():不想让某个事件在两个事件之间发生。
### --- 需要注意:
~~~ ①所有模式序列必须以.begin()开始;
~~~ ②模式序列不能以.notFollowedBy()结束;
~~~ ③“not”类型的模式不能被optional所修饰;
~~~ ④可以为模式指定时间约束,用来要求在多长时间内匹配有效。
next.within(Time.seconds(10))
三、模式的检测
### --- 模式的检测
~~~ 指定要查找的模式序列后,就可以将其应用于输入流以检测潜在匹配。调用CEP.pattern(),
~~~ 给定输入流和模式,就能得到一个PatternStream。
val input:DataStream[Event] = …
val pattern:Pattern[Event,_] = …
val patternStream:PatternStream[Event]=CEP.pattern(input,pattern)
四、匹配事件的提取
### --- 匹配事件的提取
~~~ 创建PatternStream之后,就可以应用select或者flatSelect方法,从检测到的事件序列中提取事件了。
~~~ select()方法需要输入一个select function作为参数,每个成功匹配的事件序列都会调用它。
~~~ select()以一个Map[String,Iterable[IN]]来接收匹配到的事件序列,其中key就是每个模式的名称,
~~~ 而value就是所有接收到的事件的Iterable类型。
def selectFn(pattern : Map[String,Iterable[IN]]):OUT={
val startEvent = pattern.get(“start”).get.next
val endEvent = pattern.get(“end”).get.next
OUT(startEvent, endEvent)
}
~~~ flatSelect通过实现PatternFlatSelectFunction实现与select相似的功能。
~~~ 唯一的区别就是flatSelect方法可以返回多条记录,
~~~ 它通过一个Collector[OUT]类型的参数来将要输出的数据传递到下游。
process
select
五、超时事件的提取
### --- 超时事件的提取
~~~ 当一个模式通过within关键字定义了检测窗口时间时,部分事件序列可能因为超过窗口长度而被丢弃;
~~~ 为了能够处理这些超时的部分匹配,select和flatSelect API调用允许指定超时处理程序。
~~~ # Flink CEP 开发流程:
~~~ DataSource 中的数据转换为 DataStream;
~~~ 定义 Pattern,并将 DataStream 和 Pattern 组合转换为 PatternStream;
~~~ PatternStream 经过 select、process 等算子转换为 DataStraem;
~~~ 再次转换的 DataStream 经过处理后,sink 到目标库。
### --- select方法:
SingleOutputStreamOperator<PayEvent> result = patternStream.select(orderTimeoutOutput, new PatternTimeoutFunction<PayEvent,
PayEvent>() {
@Override
public PayEvent timeout(Map<String, List<PayEvent>> map, long l) throws
Exception {
return map.get("begin").get(0);
}
}, new PatternSelectFunction<PayEvent, PayEvent>() {
@Override
public PayEvent select(Map<String, List<PayEvent>> map) throws Exception {
return map.get("pay").get(0);
}
});
~~~ # 对检测到的模式序列应用选择函数。对于每个模式序列,调用提供的{@link PatternSelectFunction}。
~~~ 模式选择函数只能产生一个结果元素。
~~~ 对超时的部分模式序列应用超时函数。
~~~ 对于每个部分模式序列,调用提供的{@linkPatternTimeoutFunction}。
~~~ 模式超时函数只能产生一个结果元素。
~~~ 您可以在使用相同的{@link OutputTag}进行select操作的{@link SingleOutputStreamOperator}
~~~ 上获得由{@link SingleOutputStreamOperator}生成的{@link SingleOutputStreamOperator}
~~~ # 生成的超时数据流。
~~~ @param timedOutPartialMatchesTag 标识端输出超时模式的@link OutputTag}
~~~ @param patternTimeoutFunction 为超时的每个部分模式序列调用的模式超时函数。
~~~ @param patternSelectFunction 为每个检测到的模式序列调用的模式选择函数。
~~~ @param 产生的超时元素的类型
~~~ @param 结果元素的类型return {@link DataStream}其中包含产生的元素和在边输出中产生的超时元素。
### --- 获取{@link DataStream}该{@link DataStream}包含由操作发出到指定{@link OutputTag}的边输出的元素。
DataStream<PayEvent> sideOutput = result.getSideOutput(orderTimeoutOutput);
Walter Savage Landor:strove with none,for none was worth my strife.Nature I loved and, next to Nature, Art:I warm'd both hands before the fire of life.It sinks, and I am ready to depart
——W.S.Landor
分类:
bdv020-flink
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· DeepSeek 开源周回顾「GitHub 热点速览」