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

1.UpdateListener

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

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

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

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

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

2.Insert and Remove Stream

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

  1. EPL:select * from User

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

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

  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要改写一下:

  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:

  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:

  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基本一样,下面给大家展示一下:

  1. // 统计进入的5个Apple事件,amount的总数是多少
  2. select sum(amount) from Apple.win:length_batch(5)
  3. // 统计进入的5个Apple事件,amount的总数是多少,并按照price分组
  4. select price, sum(amount) from Apple.win:length_batch(5) group by price
  5. // 统计进入的5个Apple事件,amount的总数和name,并按照price分组
  6. 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的话,就只会有一个事件触发监听器了。

Esper学习之三:进程模型的更多相关文章

  1. Esper学习之六:EPL语法(二)

    中秋三天,说闲也不闲,调调工作的代码,倒还解决不少问题.不过也是因为最近工作忙的缘故,Esper被我冷落不少日子了,趁着今天最后一天,赶紧写一篇出来. 从上一篇开始说EPL的语法,主要是关于注解的.今 ...

  2. Esper学习之四:Context

    上周末打球实在太累了,就没来得及更新,只是列了个提纲做做准备,发现Context还是有很多内容的.结果也花了不少时间才写完,所以这篇需要各位慢慢消化,并且最好多写几个例子加深理解. 如果有不了解Esp ...

  3. Esper学习之十二:EPL语法(八)

    今天的内容十分重要,在Esper的应用中是十分常用的功能之一.它是一种事件集合,我们可以对这个集合进行增删查改,所以在复杂的业务场景中我们肯定不会缺少它.它就是Named Window. 由于本篇篇幅 ...

  4. 操作系统学习笔记----进程/线程模型----Coursera课程笔记

    操作系统学习笔记----进程/线程模型----Coursera课程笔记 进程/线程模型 0. 概述 0.1 进程模型 多道程序设计 进程的概念.进程控制块 进程状态及转换.进程队列 进程控制----进 ...

  5. Nginx学习之六-nginx核心进程模型

    一.Nginx整体架构 正常执行中的nginx会有多个进程,最基本的有master process(监控进程,也叫做主进程)和woker process(工作进程),还可能有cache相关进程. 一个 ...

  6. Nginx学习——进程模型(master 进程)

    进程模型 Nginx分为Single和Master两种进程模型.Single模型即为单进程方式工作,具有较差的容错能力,不适合生产之用.Master模型即为一个master进程+N个worker进程的 ...

  7. nginx学习(三):nginx的进程模型

    概述 nginx 进程分为 master进程和work进程 1.打开配置文件查看,这里我修改为2 [root@xxx conf]# vim nginx.conf #user nobody; worke ...

  8. Nginx学习笔记(一):Nginx 进程模型 / 事件处理模型

    Nginx 进程模型 ​​​​ 多进程模型 进程间相互独立,无需加锁,且互不影响: 一个进程退出了不影响其他的进程运行,降低风险: 当请求到来,多个 worker 通过竞争 accrpt_mutex ...

  9. Nginx基础知识学习(安装/进程模型/事件处理机制/详细配置/定时切割日志)

    一.Linux下Nginx的安装 1.去官网 http://nginx.org/download/下载对应的Nginx安装包,推荐使用稳定版本. 2.上传Nginx到Linux服务器. 3.安装依赖环 ...

随机推荐

  1. C#基础 ---------------单利模式

    一.引言 最近在设计模式的一些内容,主要的参考书籍是<Head First 设计模式>,同时在学习过程中也查看了很多博客园中关于设计模式的一些文章的,在这里记录下我的一些学习笔记,一是为了 ...

  2. Python_问题收录总结

    python IndentationError: unindent does not match any outer indentation level的问题 用python编个作业,我先用的note ...

  3. 逻辑卷管理LVM 扩容LV容量实例(一)

    实验环境: 一台Linux 服务器添加两块硬盘,一块硬盘容量30G,另一块硬盘容量50G,采用VMware Workstation虚拟机进行模拟实验. 30G硬盘先分成一个分区,分区大小为25G,再创 ...

  4. C# ListView控件使用简介

    ListView控件在各类程序中,具有数据显示直观,操作方便的特点.所以使用率极高,但控件的各类参数众多,很多初学者不易掌握,在此列举该控件的一些常用方法,属性,希望对初学者有一定帮助. //2005 ...

  5. ubuntu14.04_64位安装tensorflow-gpu

    第一步(可直接跳到第二步):安装nvidia显卡驱动 linux用户可以通过官方ppa解决安装GPU驱动的问题.使用如下命令添加Graphic Drivers PPA: sudo add-apt-re ...

  6. c fopen fread 错误

    真的被,读取一个txt文本,结果一个早上都没搞好 程序如下: 能看出哪里有问题么,输出字符串,得到的结果后面有“屯”或则 “烫”,单个字符输出来也有,为何,搜啊搜,改txt的内容,依旧不行 最后 改f ...

  7. memcached监控工具

    最简单和最直接的方式是在启动memcached的时候加入-vv参数,从而在控制台打印每次客户端的请求和相应,这非常适合开发.另外一种较为直接的方式是通过telnet进行查看,例如:若server为本机 ...

  8. Linux系统下wetty安装和使用说明

    1. Wetty简介 Wetty是使用Node.js和websockets开发的一个开源Web-based SSH.关于Web-based SSH的更多资料请参考https://en.wikipedi ...

  9. Linux 目录下属性查看操作

    1. 查看当前目录所有文件和文件夹的大小 方法一: $du -sh * 或 $du -h -d 0 * '-d 0' 代表查询目录的深度为0 ,也就是当前目录,'-d 3' 表示文件目录深度为3,可以 ...

  10. Java使用ListIterator逆序ArrayList

    对于列表而言,除了Iterator,还提供了一个功能更加强大的ListIterator.它可以实现逆序遍历列表中的元素.本示例将使用其逆序遍历ArrayList. 思路分析:要逆序遍历某个列表,首先要 ...