flink-22 flink复杂事物处理机制CEP

CEP概念

CEP是Complex Event Processing三个单词的缩写,表示复杂事件处理,是一种基于流处理的技术,CEP是Flink专门为我们提供的一个基于复杂事件监测处理的库,CEP通过一个或多个由简单事件构成的事件流通过一定的规则匹配,然后输出用户想得到的数据,满足规则的复杂事件。
CEP复杂事件处理主要应用于防范网络欺诈、设备故障检测、风险规避和智能营销等领域。Flink 基于 DataStrem API 提供了 FlinkCEP 组件栈,专门用于对复杂事件的处理,帮助用户从流式数据中发掘有价值的信息

简单来说
CEP就是用户自己制定了一些规则,然后把这些规则应用到实时不断产生的数据流中,最后利用规则对数据做匹配筛选处理

CEP的主要特点

  • 目标
    • 从有序的简单事件流中发现一些高阶特征
  • 输入
    • 一个或多个由简单时间构成的事件流
  • 处理
    • 识别简单时间之间的内在联系,多个符合一定规则的简单时间构成复杂时间
  • 输出
    • 满足规则的复杂时间

在这里插入图片描述

Pattern API

Flink CEP中提供了pattern API用于对输入流数据的复杂时间规则定义,并从时间流中抽取事件结果。
包括四个步骤

  • 1)输入事件流的创建
  • 2)Pattern的定义
  • 3)Pattern应用在事件流上检查
  • 4)选取结果

输入流的创建

//获取数据输入流
val input: DataStream[Event] = ...

Pattern的定义

Pattern有两种循环模式:

  • 单次执行模式
    • 单次执行模式一次只接受一个事件
  • 循环执行模式
    • 循环执行模式可以接受一个或者多个事件

单次执行模式可以通过指定循环次数变为循环执行模式
每种模式能给将多个条件组合停用到同一事件之上,条件组合可以通过where方法进行叠加

  • 每个Pattern通过begin方法定义
//[]表示要匹配的类型,可以是event、object、string等
//start_pattern为对其起的别名
val start = Pattern.begin[Event]("start_pattern")
  • 下一步,通过Pattern.where()方法在Pattern上指定Conditition。只有当Condition满足之后,当前的Pattern才会接受事件
start.where(_.getID == "9527")

设置循环次数

对于已经创建好的Pattern,可以指定循环次数,形成循环执行的Pattern

  • times
    • 通过times指定固定的循环次数
//指定循环触发4次 
start.times(4); 
//可以执行触发次数范围,让循环执行次数在该范围之内 
start.times(2, 4);
  • optiional
    • 通过optional指定要么不触发,要么触发指定次数
tart.times(4).optional()
start.times(2, 4).optional()
  • greedy
    • 通过greedy将Pattern标记为贪婪模式,在Pattern匹配成功的前提下,会尽可能多次触发
//触发2、3、4次,尽可能重复执行 
start.times(2, 4).greedy()
//触发0、2、3、4次,尽可能重复执行 
start.times(2, 4).optional().greedy()
  • oneOrMore
    • 通过onOrMore方法指定触发一次或者多次
// 触发一次或者多次 
start.oneOrMore()
//触发一次或者多次,尽可能重复执行 
start.oneOrMore().greedy() 
// 触发0次或者多次 
start.oneOrMore().optional() 
// 触发0次或者多次,尽可能重复执行 
start.oneOrMore().optional().greedy()
  • timesOrMor
    • 通过timesOrMore方法可以指定触发固定此时以上。如:执行两次以上
/ 触发两次或者多次 
start.timesOrMore(2);
// 触发两次或者多次,尽可能重复执行 
start.timesOrMore(2).greedy()
// 不触发或者触发两次以上,尽可能重执行 
start.timesOrMore(2).optional().greedy()

定义触发条件

每个模式都需要指定触发条件,作为事件进入到该模式是否接受的判断依据,当时间中的数值满足了条件是,便进行下一步操作。

在Flink CEP中通过以下方法来指定条件

  • pattern.where()
  • pattern.or()
  • pattern.until()

Pattern 条件有以下三种类型

  • Simple Conditions(简单条件)
  • Combining Conditions(组合条件)
  • Stop condition (终止条件)

Simple Conditions(简单条件)

  • 只要根据事件中的字段信息进行判断,是否接受该时间
// 把ID为9527的事件挑选出来
start.where(_.getID == "9527")

Combining Conditions(组合条件)

  • 通过where、or将简单条件进行合并(where相当于and)
// 把ID为9527或者年龄大于30的事件挑选出来 
val start = Pattern.begin[Event]("start_pattern")
				 .where(_.callType=="success").or(_.age >30)//.where(_.resType=="success") 多个where相当于and

Stop condition (终止条件)

如果程序中使用了

  • oneOrMore
  • oneOrMore().optional()方法

还可以指定停止条件,否则模式中的规则会一直循环下去,如下终止条件通过 until()方法指定

start.oneOrMore.until(_.getID == "123")

模式序列

将相互独立的模式进行组合然后形成模式序列。模式序列基本的编写方式和独立模式一 致,各个模式之间通过邻近条件进行连接即可。

  • 严格相邻:next
    • 严格邻近条件中,需要所有的事件都按照顺序满足模式条件,不允许忽略任意不满足的模式
//示例
begin("first").where(_.name='a').next("second").where(.name='b')
//当且仅当数据为a,b时,模式才会被命中。如果数据为a,c,b,由于a的后面跟了c,所以a会被直接丢弃,模式不会命中。
  • 宽松相邻:followedBy
    • 在宽松邻近条件下,会忽略没有成功匹配模式条件,并不会像严格邻近要求得那么高
/示例
begin("first").where(_.name='a').followedBy("second").where(.name='b')
//当且仅当数据为a,b或者为a,c,b,,模式均被命中,中间的c会被忽略掉。
  • 非确定宽松邻近:followedByAny
    • 和宽松邻近条件相比,进一步放宽条件,之前已匹配过的事件也可以再次使用
//示例
begin("first").where(_.name='a').followedByAny("second").where(.name='b')
//当且仅当数据为a,c,b,b时,对于followedBy模式而言命中的为{a,b},
//对于followedByAny而言会有两次命中{a,b},{a,b}

在这里插入图片描述
除以上模式序列外,还可以定义“不希望出现某种近邻关系

  • notNext()
    • 不想让某个事件严格紧邻前一个事件发生
  • notFollowedBy()
    • 不想让某个事件在两个事件之间发生

注意

  • 1、所有模式序列必须以 .begin() 开始

  • 2、模式序列不能以 .notFollowedBy() 结束

  • 3、“not” 类型的模式不能和optional关键字同时使用

  • 4、此外,还可以为模式指定时间约束,用来要求在多长时间内匹配有效

//指定模式在10秒内有效 
pattern.within(Time.seconds(10))

Pattern检测

调用CEP.pattern()方法,给定输入流和模式,就能得到一个PatternStream

//Pattern检测
val patternStream = CEP.pattern[Event](dataStream,pattern)

选取结果

得到PatternStream 类型的数据集后,接下来数据获取都基于PatternStream 进行。该数据集中只包含所有的匹配事件
Flink CEP提供两种方法从PatternStream 提取事件结果

  • select
  • flatSelect

通过select抽取正常事件

在PatternStream 的Select方法中传入自定义的Select Function
函数解析如下:

  • 参数: Map[String, Iterable[IN]]
  • Map中的key:模式序列中的Pattern名称
  • Map中的value:Pattern 所接受的事件集合,格式为输入事件的数据类型
def selectFunction(pattern : Map[String, Iterable[IN]]): OUT = {
   
    //获取pattern中的start
     Event val startEvent = pattern.get("start_pattern").get.next
    //获取Pattern中middle
    Event val middleEvent = pattern.get("middle").get.next 
    //返回结果 
    OUT(startEvent, middleEvent)

}

通过flatSelect抽取正常事件

  • Flat Select Funciton与Select Function 相比,可以返回任意数量的结果。
  • Flat Select Funciton使用Collector 作为返回结果的容器,可以将需要出的事件都放置在Collector中返回
def flatSelectFunction(pattern : Map[String, Iterable[IN]]),collector:Collector[OUT] = {
   
    //获取pattern中的start
     Event val startEvent = pattern.get("start_pattern").get.next
    //获取Pattern中middle
    Event val middleEvent = pattern.get("middle").get.next 
    //并根据startEvent的Value数量进行返回
    for (i <- 0 to startEvent.getValue) {
    
        collector.collect
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值