Esper剖析

时间:2023-03-08 17:19:21

Esper剖析

最近在看论文,发现文中有些语言自己未曾见过,经过一番搜索,才发觉是自己接触到了新知识。

官网: )esper的核心包包含了EPL语法解析引擎,事件监听机制,事件处理等核心模块。

(2)esper的io包含从各种数据源读取数据以及将输出结果写入各种数据源,包括excel,database,JMS,http,socket,XML。

1. Event对象:ESPER处理的事件的最小单位,一个任意的JavaBean对象,属性支持简单的java类型、数组、map、以及嵌套JavaBean,很灵活,下面是一个简单的Event对象:

秒内OrderEvent的price的平均值,那该怎么做呢?一般的做法需要做个后台线程来做3秒的时间统计,时间到了再做后续处理,虽然不复杂,但是也挺繁琐的。

来看看EPL是怎么做的:

秒的时间窗口,avg(price)就是统计了3秒内的OrderEvent对象的price的平均值。

长度窗口:长度窗口和时间窗口比较类似

个Event的,avg(price)就是统计了最近10个的OrderEvent对象的price的平均值。

EPL语法

EPL,全称Event Processing Language,是一种类似SQL的语言,包含了SELECT, FROM, WHERE, GROUP BY, HAVING 和 ORDER BY子句,同时用事件流代替了table作为数据源,并且能像SQL那样join,filtering和aggregation。所以如果各位有SQL基础的话,简单的EPL很容易掌握。除了select,EPL也有insert into,update,delete,不过含义和SQL并不是很接近。另外还有pattern和output子句,这两个是SQL所没有的。EPL还定义了一个叫view的东西,类似SQL的table,来决定哪些数据是可用的,Esper提供了十多个view,并且保证这些view可以被重复使用。而且用户还可以扩展view成为自定义view来满足需求。在view的基础上,EPL还提供了named window的定义,作用和view类似,但是更加灵活。。。

Select Clause和From Clause。这个两个可以说是写EPL必备,要想得到事件流的处理结果,基本上就靠他们俩了(Pattern除外)。

Select Clause

1.查询事件流的所有属性及特定属性

EPL的select和SQL的select很相近,SQL用*表示查询表的所有字段,而EPL用*表示查询事件流的所有属性值。SQL查询某个字段名,直接在select后跟字段名就ok,EPL也是将要查询的属性名放在select之后。若查多个属性值,则用逗号分割。和SQL一样,EPL查询属性也可以设置别名。示例如下:

秒的Apple的平均价格

个Apple的价格总和的两倍

个Apple的价格,并用函数计算后再算平均值

秒内进入的事件即为一个事件流集合),则所有聚合函数都返回null。

4.Insert into

4.1 简单用法

EPL的Insert into和SQL的有比较大的区别。SQL是往一张表里插入数据,而EPL是把一个事件流的计算结果放入另一个事件流,然后可以对这个事件流进行别的计算。所以Insert into的一个好处就是可以将是事件流的计算结果不断级联,对于那种需要将上一个业务的结果数据放到下一个业务处理的场景再适合不过了。除此之外,Insert into还有合并多个计算结果的作用。到这里相信大家已经对他越来越好奇了,不急,咱们先来看看语法:

insert [istream | irstream | rstream] into event_stream_name [ (property_name [, property_name] ) ]

event_stream_name定义了事件流的名称,在执行完insert的定义之后,我们可以使用select对这个事件流进行别的计算。

istream | irstream | rstream表示该事件流允许另一个事件的输入/输入数据和输出/输出数据能够进入(解释好像很绕。。一会儿看例子就能明白了)

property_name表示该事件流里包含的属性名称,多个属性名之间用逗号分割,并且用小括号括起来。

上面的说明可能不是很好理解,咱们先看个例子:

//将新进入的Asus事件传递到Computer,且Asus的id,size和Computer的cid,csize对应

insert into Computer(cid,csize) select id,size from Asus

// 第二种写法

insert into Computer select id as cid, size as csize Asus

从例子中可以看到,insert into需要配合select进行使用,以表明前一个事件流有哪些计算结果将进入insert into定义的事件流。并且在select中的字段要和insert里的事件流的属性要对应(这里指的对应是数据类型对应,而且属性数量也必须一样)。如果说insert定义的事件流名称在之前已经定义过(insert into中定义的除外),重名是不允许的。

我个人推荐第二种写法,通过as设置的别名即为insert定义的事件流的属性,这样可以避免属性的个数不一致的错误。

参考博文:

http://blog.****.net/luonanqin/article/details/9900295