复杂事件处理引擎—Esper⼊门(第⼆弹)
时间正则表达式java说明:
以下内容,可以参考Esper官⽅⽹站《Qucik start & Tutorial 》(顺序做了部分调整)。 PS:因为英语⽔平有限(⼤学期间刚过CET4的英语⼩盲童⼀枚),翻译很烂(⾃⼰都感觉不能直视),描述不清的,可以随时问。⼀有时间,将给予解释。
Tutorial (教程)部分
1、简介(该部分在⼊门第⼀弹中有提起)
Esper 是⼀个事件流处理和事件关联的引擎(CEP,complex event processing 复合事件处理)。作为实时事件驱动框架,当事件流中有事件条件发⽣时,Esper能够触发⾃定义动作(POJO)。Esper也是为了⼤量事件关联⽽设计,当有数百万的事件进来时,不能⽤经典的数据库架构来存储所有事件。
定制的事件处理语⾔EPL,允许表达丰富的事件条件、关联性,也可跨越事件窗⼝,从⽽最⼤限度的减少为应对复杂情况⽽必须建⽴系统的开发难度。
Esper是轻量级的java内核实现,其可以完全嵌⼊到任何的java进程、javaEE应⽤服务器或者给予java的ESB(企业服务总线)。Esper可以很快完成传⼊的⼤量消息或者事件处理的应⽤程序。
【总结】Esper是⼀个事件处理和复杂事件关联处理的java内核的轻量级引擎。对于⼤量事件的处理,能够⽤最短的时间做出反应,触发相应的操作。另外,为Esper量⾝定制的事件处理语⾔——类SQL语⾔,对于表达事件的条件以及关联关系的处理等⾮常⽅便。
2、事件流和复杂事件
信息对于作出明智的选择是⾄关重要的。不仅现实⽣活中这是事实,⽽且在计算机处理中尤其是⼀些领域,⽐如⾦融、欺诈检测、商业智能或是战场操作等,也是很重要的。信息从不同的来源,以消息或者事件的形式流动,如股票价格在某⼀特定时间的状态需要给出⼀个提⽰。也就是说,看离散的数据⼤部分时间是没有意义的。交易者需要看到⼀段时间的股票⾛势,以便结合其他信息在合适的时间做出最好的交易。
⼀条⼀条的离散事件是没有意义的,事件流——⼀个⽆限的事件集合——可认为是⼀个滑动的窗⼝,进⼀步关联是⾮常有意义的,并⽤最⼩的延迟对事件做出反应,对有效⾏动和竞争优势是⾄关重要的。
【总结】事件流其实⼀个个离散的事件串接⽽成。现实中对于事件流的监控或者处理,⽐如股票信息等,需要实时性的计算其⾛势,以便能够及时的获取有价值数据。事件流在Esper中是⼀个滑动的窗⼝,对事件关联处理等⾄关重要。
3、Esper
关系型数据库或者基于消息的系统⽐如JMS,真的很难处理时间数据和实时查询。事实上,数据库需要⼀个明确的查询来返回有意义的数据,并且在数据放⽣变化时不适合推送数据。JMS系统是⽆状态的,需要开发⼈员⾃⼰实现这个时间和聚合的逻辑。相⽐之下,Esper提供了更⾼的抽象和智能,可以认为是数据库的倒置:不是存储数据,⽽是对存储的数据运⾏查询,Esper允许应⽤程序存储查询,并让数据运⾏通过。当满⾜查询的条件发⽣时,Esper会做出实时的响应。执⾏模块是持续的,⽽不是只有在查询提交的时候。这个概念是EDA(事件驱动架构)的关键基础,在过去的10年,甚⾄更久都⼀直在积极的研究。然⽽,现实中对该系统重要性的认知最近才开始出现。
在Esper中,定制的EPL允许在引擎中注册查询。监听类(POJO类)会在事件满⾜EPL条件的时候由引擎进⾏调⽤。EPL能够表达复杂的匹配条件,包括事件窗⼝、事件流关联、过滤、聚合以及排序等。Esper statement也可以通过“followed by ” 即“->”条件从多个简单的事件中获取复杂事件。事件可以被描述成JavaBean类、传统的java类、XML或者是Map,作为消息发布者,促进重⽤现有的系统。
【总结】在处理实时性的数据时,⽐如⼼跳监控、股票价格⾛势等,Esper相对于关系型数据库有天然的优势,Esper不需要对完成的数据的存储,便可以完成数据的实时查询处理,从这点看,更像是数据库的倒置——试想⼀下,数据库是先存储数据,通过编译解析SQL,完成已存储数据的查询,Esper则
是先编译EPL语句,形成⼀个过滤(或处理)层(或者⽹),实时过来的数据,通过这个过滤层完成有效事件的筛选或形成有效事件。Esper的事件处理语⾔——EPL,是类SQL语⾔,其select 语句、from语句、where语句以及group by 、having等,甚⾄包括⼤部分的聚合函数等,都和标准的SQL语⾔⼀致。在EPL规则的编写上,对于有数据库开发经验的⼈来说,上⼿⼗分容易。
4、开发事件驱动应⽤
⽤Esper来开发事件驱动应⽤并不困难。⼤概有下⾯的⼏步:
1> 通过分析业务域和定义探测的情景或者需要报告的信息,定义应⽤程序应该完成的功能或任务。
2> 定义性能要求,特别是吞吐量和延迟。
3> 确定从什么地⽅获取事件。
4> 根据业务确定事件格式和事件内容。
5> 设计导致复杂事件的事件关系。
6> 事件源。
7> 设计事件表⽰类型:java类、map、或XML等
8> 定义EPL语句,⽤于匹配模式和流的处理。
9> ⽐如,⽤CSV适配器作为事件模拟⼯具,测试检测场景,或产⽣加载加载事件。
10> 在最终的环境上,测试吞吐量和延迟。
5、设计事件表⽰⽅式
在Esper当中,java类是⼀种简单、丰富且通⽤的事件表⽰⽅式。通过接⼝和超类,java类提供了继承性和多态性,通过⼀个对象graph,就可以表⽰⼀个复杂的业务域。Maps或XML也是事件表⽰的⼀种⽅式。
6、事件流分析
EPL语句从⼀个或者多个事件流中派⽣和聚合信息,加⼊或合并事件流,并将⼀个时间流的结果提供给后续的语句。EPL在select语句
和where语句的使⽤上,和SQL很相似。不过EPL语句⽤事件流和views替换了数据库的表格。和SQL
中表格相似,views定义了可⽤于查询和过滤的数据。Views可以表⽰为⼀个事件流上的⼀个窗⼝。Views也可以排序事件、从事件属性获取统计数据、进⾏事件分组或者处理唯⼀的事件属性值。
下⾯的EPL语句⽤于计算股票事件过去30s的平均价格:
select avg(price) from StockTickEvent.win:time(30 sec)
下⾯EPL返回的是前100条股票事件的平均值:
select symbol, avg(price) as averagePrice
from StockTickEvent.win:length(100)
group by symbol
下⾯的例⼦关联了两个事件流。第⼀个事件流由欺诈告警事件组成,⽤于保存过去30分钟的事件信息。第⼆个流则是withdrawal事件,⽤来保存过去30秒的事件。这两个流通过account number进⾏关联:
select fraud.accountNumber as accntNum, fraud.warning as warn, withdraw.amount as amount,
MAX(fraud.timestamp, withdraw.timestamp) as timestamp, 'withdrawlFraud' as desc
from FraudWarningEvent.win:time(30 min) as fraud,
WithdrawalEvent.win:time(30 sec) as withdraw
where fraud.accountNumber = withdraw.accountNumber
7、事件模式匹配
Event patterns match when an event or multiple events occur that match the pattern's definition.
⼀个或多个事件发⽣时,事件模式会匹配定义的模式(很别扭啊⊙﹏⊙b)。模式也可以是基于时间的。模式匹配时通过状态机实现的。
模式表达式可以由连接了模式操作符的过滤器表达式组成。通过在圆括号中的嵌⼊表达式,可以实现更深的模式表达式嵌套。
5类操作符:
·控制模式探测器的创建和终⽌:every
· 逻辑操作符:and、or、not
· 操作事件顺序的时间操作符:-> (紧跟着发⽣的,followed by)
· 过滤输出事件的where条件,引起模式探测器的终⽌:如,timer:within
· 和观察其他事件⼀样,观察者也观察时间事件,如 timer:interval, timer:at
下⾯是⼀些EPL的例⼦:
//模式匹配的是在接下来60秒钟IBM股票值⼤于80的所有事件
every StockTickEvent(symbol="IBM", price>80) where timer:within(60 seconds)
//每⼩时的第5分钟给出提醒:
every timer:at(5, *, *, *, *)
//当A事件发⽣时,如果后⾯跟的是B事件或C事件,则给出提醒(输出A事件)
A -> (
B or
C )
//匹配的是每⼀个EventX,如果后跟EventY事件,并且其objectID和EventX的objectID⼀样,则给出提醒(输出a事件):
every a=EventX -> every b=EventY(objectID=a.objectID)
8、模式匹配和事件流分析结合使⽤
当检测到事件序列(或没有事件发⽣)时,模式就会匹配。模式匹配的结果可以⽤于进⼀步的分析和处理。
下⾯的模式监测的是 Status事件发⽣后的10s没有相同ID的status事件发⽣的场景。整个EPL语句进⼀步计算了所有发⽣的每个ID的事件总数。
select a.id, count(*) from pattern [
every a=Status -> (timer:interval(10 sec) and not Status(id=a.id)
]
group by id
9、命名窗⼝
命名窗⼝在引擎中是全局的数据窗⼝,其可以参与到很多的语句查询,并且可以被多个statement执⾏select、insert和delete操作。命名窗⼝和关系型数据库系统的表很相似。
通过下⾯的⼏步可以创建命名窗⼝:
create window AlertNamedWindow as (origin string, priority string, alarmNumber long)
当事件到达时,可以触发⼀个select、update或delete操作。下⾯是⼀个select应⽤,简单的统计数据窗⼝中的记录⾏总数:
on TriggerEvent select count(*) from AlertNamedWindow
10、匹配-识别模式匹配(Match-Recognize Pattern Matching)
匹配-识别模式是⼀个基于正则表达式的模式匹配语法,是建议列⼊SQL的标准语法。
下⾯的匹配-识别模式,探测的是可能出现在事件中的模式,这些事件通过命名窗⼝(如上声明)保存。
这个模式查的是两个紧跟的事件,即事件之间没有相同的origin。第⼀个事件必须有⼀个“high”优先级,第⼆个事件必须是“medium”优先级。
select * from AlertNamedWindow
match_recognize (
partition by origin
igin as origin, a1.alarmNumber as alarmNumber1, a2.alarmNumber as alarmNumber2
pattern (a1 a2)
define
a1 as a1.priority = 'high',
a2 as a2.priority = 'medium'
)
11、变量(Variables)
变量是⼀个标量、对象或者事件值,可⽤于所有的statement,包括模式。变量可以⽤在EPL中任意位置的表达式中。
【总结】开发Esper应⽤时,事件类型建议采⽤Java类,对于事件信息的描述更为直观(参考<a
href="/tutorials/tutorial/quickstart.html">Quick Start</a>)。在具有复杂关系的事件设计中,不建议使⽤Map的⽅式(可参考<a href="/esper-4.9.0/doc/reference/en-US/html/performance.html#perf-tips-22">Esper参考⽂档性能部分</a>)。在EPL设计时,根据业务需求,如果能通过标准的SQL语法完成的,尽量不要使⽤匹配模式,因为在运⾏时,需要对Pattern进⾏额外的解析,其规则较SQL复杂,性能上有少许损耗。
数据窗⼝的使⽤,能够使得Esper处理更为复杂的应⽤场景,⽐如与分布式缓存、静态数据的使⽤等。变量不难理解,不管是⾼级的开发语⾔如java、C/C++,还是脚本语⾔如ruby、JS等,都有变量的概念,其使⽤范围,仅限于当前的Esper引擎实例。
另外,本节所描述的信息,如EPL、数据窗⼝等概念会在后续的更新中详细描述。敬请期待!!
注:转载请注明出处!谢谢!
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论