zoukankan      html  css  js  c++  java
  • Esper学习之三:进程模型

     之前对Esper所能处理的事件结构进行了概述,并结合了例子进行讲解,不清楚的同学请看Esper学习之二:事件类型。今天主要为大家解释一下Esper是怎么处理事件的,即Esper的进程模型。

    1.UpdateListener

    UpdaterListener是Esper提供的一个接口,用于监听某个EPL在引擎中的运行情况,即事件进入并产生结果后会通知UpdateListener。接口如下

    [java] view plaincopy
     
    1. package com.espertech.esper.client;  
    2.   
    3. import com.espertech.esper.client.EventBean;  
    4.   
    5. public interface UpdateListener  
    6. {  
    7.     public void update(EventBean[] newEvents, EventBean[] oldEvents);  
    8. }  

    接口很简单,就一个update方法,其中包括两个EventBean数组,至于两个参数的含义稍后再说。EventBean中有一个最常用的get方法,是用来得到EPL中某个字段的值。例如:

    [sql] view plaincopy
     
    1. EPL:select name from User  
    2. //假设newEvents长度为一  
    3. newEvents[0].get("name")能得到进入的User事件的name属性值  
    4.   
    5. EPL:select count(*) from User.win:time(5 sec)  
    6. //假设newEvents长度为一  
    7. newEvents[0].get("count(*))能得到5秒内进入引擎的User事件数量有多少  

    get方法最常用,此外还有getUnderlying等方法,以后会专门写一篇介绍EventBean的。

    2.Insert and Remove Stream

    Insert表示进入引擎,Remove表示移出引擎,事件在Esper中会因为某类EPL才会经历这两种状态。对应于UpdateListener接口就是newEvents和oldEvents,因为处于这两种状态的事件不一定只有一个,所以newEvents和oldEvents就是数组形式。举个例子说明下

    [sql] view plaincopy
     
    1. EPL:select * from User  

    从此图可以看出,随着时间推移,每个进入到引擎的W事件都是newEvents,即Insert Stream。W后括号里的值为属性值,可忽略。

    有人可能要问了,为什么这里oldeEvents什么都没有。那是因为EPL的关系。看下面的例子

    [sql] view plaincopy
     
    1. EPL:select * from User.win:length(5)  

    注:win:length(5)是个view,详细的后面会专门讲解,这里先暂时理解为Esper开放一个空间并最多可同时存放5个事件(此空间其实就是大小为5的数组)

           由图可知,length window可存放w1,w2等事件,在w6事件进入之前,每个事件进入都属于newEvents。直到w6进入后,length window不能容纳w1~w6的事件,必须把w1事件移出,即w1为oldEvents。length window就像一个队列,每当事件进入队列时,就会触发updateListener并告知有新事件进入。当队列满了,再进入一个新事件时,Esper会触发UpdateListener告知有新事件进入并且有旧事件移出,正如上图所示的w6和w1。

    实际上这个EPL触发监听器都只能看到newEvents,看不到oldEvents。如果想看到oldEvents,EPL要改写一下:

    [sql] view plaincopy
     
    1. EPL:select irstream * from User.win:length(5)  


           默认情况下,Esper认为你只想让newEvents触发监听器,即istream(insert stream)。如果想让oldEvents触发监听器,那么为rstream(remove stream)。如果两个都想,那么为irstream。当然这个默认情况是可以配置的,以后会说到这个问题。

           不过对于rstream,在我看来他有个bug,因为在运行时我发现,oldEvents触发监听器时,理论上应该是oldEvents这个参数有值,就算他没说明,按照常理推断也应该是oldEvents有值,但是实际上是newEvents有值,oldEvents为null。虽然说数据没有错,但是这个似乎不合常理。

    注:上面这段话是错误的,后来我看到第五章的时候,文档有明确说明当用rstream关键字的时候,过期事件是发到newEvents的,不会发到oldEvents,所以oldEvents是null。只不过我觉得这样会给人怪怪的感觉。。(这段话回复了评论里的joy_91 ,感谢!)

    3.Filter and Where-Clause

    EPL有两种过滤事件的方式,一种是过滤事件进入view(可以把view理解为一个窗口),即Filter。另一种是让事件都进入view,但不触发UpdateListener,即Where子句。关于这两种语法后面会详细讲解,这里就只是简单介绍。

    Filter:

    [sql] view plaincopy
     
    1. // Apple事件进入Esper,只有amount大于200的才能进入win:length,并且length长度为5  
    2. EPL:select * from Apple(amount>200).win:length(5)  


    从图上可以看出,只有amount大于200,Esper才允许Apple事件进入view,并且作为一个newEvent触发UpdateListener

    Where-Clause:

    [sql] view plaincopy
     
    1. // Apple事件进入Esper并进入win:length(5),但是只有amount大于200的才能触发UpdateListener  
    2. EPL:select * from Apple.win:length(5) where amount>200  


    由图上可以看出,Apple事件先进入view,然后才被where子句过滤,以至于被过滤掉的事件不会作为newEvent触发UpdateListener

    其实单看两个EPL,就能发现一个过滤是在进入view前,一个过滤是在view后,所以大家在应用的时候要注意。PS:在我写这段的时候才发现以前认为这两种是一样的效果是错误滴- -!

    4.Aggregation and Grouping

    之前说过EPL是类SQL语法,所以也会有聚合和分组的功能。语法和SQL基本一样,下面给大家展示一下:

    [sql] view plaincopy
     
    1. // 统计进入的5个Apple事件,amount的总数是多少  
    2. select sum(amount) from Apple.win:length_batch(5)  
    3.   
    4. // 统计进入的5个Apple事件,amount的总数是多少,并按照price分组  
    5. select price, sum(amount) from Apple.win:length_batch(5) group by price  
    6.   
    7. // 统计进入的5个Apple事件,amount的总数和name,并按照price分组  
    8. select price, name, sum(amount) from Apple.win:length_batch(5) group by price  

           最后一个和前一个的区别在于name也在统计的范围内,所以当name和price都一样的两个事件进入Esper,会有两个一模一样的事件作为newEvent触发UpdaterListener,即price,name,sum(amount)都一样。当然要是group by name, price的话,就只会有一个事件触发监听器了。

  • 相关阅读:
    python常用函数总结 分类: python基础学习 2014-02-07 14:12 260人阅读 评论(0) 收藏
    classmethod类方法 分类: python 小练习 python基础学习 2014-02-07 10:36 214人阅读 评论(0) 收藏
    Python模块功能在实际应用方案中的相关功能的介绍 分类: database 2014-01-29 16:37 261人阅读 评论(0) 收藏
    Python中使用MySQLdb连接MySQL 分类: database 2014-01-29 15:37 358人阅读 评论(0) 收藏
    Ubuntu下彻底卸载mysql、安装mysql、及MySQLdb模块 分类: ubuntu 问题总结 database 2014-01-23 13:49 2560人阅读 评论(0) 收藏
    在Ubuntu上安装MySQLdb 分类: database 问题总结 ubuntu 2014-01-23 10:58 771人阅读 评论(0) 收藏
    Ubuntu 12.04 安装mysql及mysql-python 分类: python Module ubuntu database 2014-01-23 10:07 615人阅读 评论(0) 收藏
    Reading package lists... Error! 解决方案 分类: ubuntu database 问题总结 2014-01-23 09:45 1546人阅读 评论(0) 收藏
    shell技巧之多行改写成一行 分类: ubuntu 2014-01-22 18:26 268人阅读 评论(0) 收藏
    50. Tomcat 集群部署
  • 原文地址:https://www.cnblogs.com/yudar/p/4872566.html
Copyright © 2011-2022 走看看