复合事件处理(Complex Event Processing)介绍提到了开源的Esper,NEsper 是一个事件流处理(Event Stream Processing,ESP)和复杂事件处理(Complex Event Processing,CEP)的系统,它可以监测事件流并当特定事件发生时触发某些行动——可看作是把数据库反过来,语句是固定的,而数据流进进出出。事件处理是软件行业的一个发展趋势,已有数家大厂商以及许多初创企业加入到该市场中。其常有的应用例子包括系统自动交易、BAM、RFID、高级监测系统、欺诈检测,甚至直接集成进SOA。
微软有个和SQL Server 集成的StreamInsight,但是他不是开源的,开源的NEsper 是StreamInsight之外的另一个选择。虽然StreamInsight集成在SQL Server,但是它可以不需要SQL Server的,工作起来有点像有点像数据库的倒置,Esper 也是一样的。NEsper 引擎允许应用存储查询并运行数据通过,来代替存储数据并且执行查询存储数据的工作方式。NEsper 提供两种机制来处理事件: 1、NEsper 提供了一个事件模式语言去指定基于表达式的事件模式匹配。这个模式匹配引擎是通过一个状态机来实现的。这个事件处理的方法匹配期望存在的队列或者不存在的事件或者事件的组合。它包括以时间为基础的各个事件之间的关系。 2、 NEsper 还提供事件流查询。这个样可以使事件流分析CEP应用的需求。事件流查询提供窗口、聚合、连接和分析的函数来处理事件流。这些查询是通过EPL 语句来实现的(被定制过的事件处理语言(event processing lauguage -- EPL)能够表达丰富的事件条件,相关性,尽可能的时间窗口跨度,因此在为系统开发时最小化了所需的开发精力)。EPL用于视图。视图表示需要将构造的数据放入到一个事件流中并且去驱动数据的流动。在数据流动的过程中对数据进行处理,来得到我们最后所 需要的结果。
EPL与SQL一样使用select从句和where从句。但是EPL语言使用事件流和views(视图)的概念取代了数据库中的表。与SQL语句中的表相似,EPL中的views被定义成了能为查询和过滤的数据。views有对事件进行排序,能从事件属性中得到分析数据,能够给事件分组,以及单独处理事件属性值得等功能。 下面是一个简单的EPL语句,计算了在最近30秒内股票事件流的平均价格。
select avg(price) from StockTickEvent.win:time(30 sec)
接下来的EPL语句返回了每一个特征类别再100ticks之内的平均价格。
select symbol, avg(price) as averagePrice from StockTickEvent.win:length(100) group by symbol
下面的例子连接了两个事件流。第一个事件流包含了在30分钟之内进行欺骗警告的事件。第二个事件是在最近30秒内进行退款的事件。这个事件流是通过accout 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
3.事件模式匹配 模式匹配是通过状态机实现的。(NFA、DFA之类的,我是在学编译原理时候学的)。模式的表示能够包含与模式操作相结合的过滤表达。模式表达可以嵌套。 下面是5种类型的模式操作(pattern operators):
(1)控制模式查找器的创建和终结的操作符:every
(2)逻辑操作符:and、or、not
(3)时态操作符(控制事件顺序):->
(4)where-condition(用于用于事件过滤与模式查找器的终止):比如 timer:at
(5)观察者观察的事件时间:比如 timer:interval,timer:at
下面是一个简单的模式,它给在60秒内价格大于80的IBM股票一个警告:
every StockTickEvent(symbol="IBM", price>80) where timer:within(60 seconds)
每隔5分钟发出一次警告:
every timer:at(5, *, *, *, *)
每事件A发生后,接着事件B或者事件C发生:
A -> ( B or C )
一个模式,接下来事件的一个属性需要与第一个事件的该属性匹配:
every a=EventX -> every b=EventY(objectID=a.objectID)
4.模式匹配与事件流分析的结合 当一串事件流被模式进行匹配时,模式匹配的结果能被接下来的分析和处理所应用。下面的模式描述的是在10秒之内一个事件与其接下来的事件的id不同。而这个语句则进一步统计了所有这种情况下的id分组。
select a.id, count(*) from pattern [ every a=Status -> (timer:interval(10 sec) and not Status(id=a.id)] group by id 5.命名窗口(named windows) 命名窗口是一个全局数据窗口,她能够参与许多查询语句,也能被查询、被插入、被删除。命名窗口类似于数据库系统中的表(table)的概念。 接下来我们创建一个命名窗口: create window AlertNamedWindow as (origin string, priority string, alarmNumber long) 命名窗口还可以在事件达到时触发查询、修改、删除。这里举一个统计数字的例子:
on TriggerEvent select count(*) from AlertNamedWindow
通过Esper探索事件驱动架构
Esper专栏介绍
NEsper for .NET
Esper近况:事件流处理框架
https://bitbucket.org/emertechie/syslognet
http://www.cppblog.com/mysileng/archive/2012/10/11/193182.html
CEP入门
http://blog.csdn.net/luonanqin/article/category/1557469