http://blog.csdn.net/luonanqin

上周末本来要更新第三篇的,但是因为突发事情没能完成。这周我会争取更新两篇,让感兴趣的同学一次看个够。

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

1.UpdateListener

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

[java] view plaincopy
  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中某个字段的值。例如:

[sql] view plaincopy
  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就是数组形式。举个例子说明下

[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. // 统计进入的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处理事件时的一些基本知识,对以后的深入学习是必不可少的。明天会再写一篇,内容是关于context,中文翻译为上下文我觉得不妥,我的理解是对EPL的运行增加了外在约束,想继续学习的请继续关注。

Esper——进程模型相关推荐

  1. esper java_Esper教程 —— Esper 进程模型是什么(3)

    进程模型 主要解释一下 Esper 是怎么处理事件的,即Esper的进程模型. 1.UpdateListener UpdaterListener 是 Esper 提供的一个接口,用于监听某个 EPL ...

  2. Esper学习之三:进程模型 .

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

  3. php多线程模型,PHP进程模型、进程通讯方式、进程线程的区别分别有哪些?

    PHP进程模型是一个正在执行的程序,可以分配给处理器并由处理器执行的一个实体:PHP进程通讯方式有管道及有名管道,信号,共享内存等:PHP进程线程的区别有进程是资源的分配和调度的一个独立单元,而线程是 ...

  4. php-fpm 进程通讯,PHP-FPM进程模型解析

    本文将介绍以下内容: PHP-FPM进程管理方式介绍 PHP-FPM如何与Nginx等Web服务器进行通信 先说一下PHP-FPM的进程模型,PHP-FPM采用的是Master/Worker进程模型. ...

  5. 第一次作业:Linux 2.6.32的进程模型与调度器分析

    1.前言 本文分析的是Linux 2.6.32版的进程模型以及调度器分析.在线查看  源码下载 本文主要讨论以下几个问题: 什么是进程?进程是如何产生的?进程都有那些? 在操作系统中,进程是如何被管理 ...

  6. Linux进程模型总结

    一个进程在CPU上运行可以有两种运行模式(进程状态):用户模式和内核模式.如果当前运行的是用户程序(用户代码),那么对应进程就处于用户模式(用户态),如果出现系统调用或者发生中断,那么对应进程就处于内 ...

  7. 黑马程序员Linux系统开发视频之创建守护进程模型

    黑马程序员Linux系统开发视频之创建守护进程模型 1.创建子进程,父进程退出   所有工作在子进程中进行形式上脱离了控制终端 2.在子进程中创建新会话   setsid()函数   使子进程完全独立 ...

  8. linux 进程调度类型 总结,Linux进程模型总结

    来源于网络 原创不详 Linux进程通过一个task_struct结构体描述,在linux/sched.h中定义,通过理解该结构,可更清楚的理解linux进程模型.   包含进程所有信息的task_s ...

  9. 第一次作业:深入Linux源码分析进程模型

    一.进程的概念 第一,进程是一个实体.每一个进程都有它自己的地址空间,一般情况下,包括文本区域(text region).数据区域(data region)和堆栈(stack region).文本区域 ...

最新文章

  1. Kattis - bela
  2. 【编程题】简单的四则运算
  3. C++模板中的函数式参数
  4. 《C++ Primer》7.2节练习
  5. 使用Spring 3.1和基于Java的配置构建RESTful Web服务,第2部分
  6. 飞畅科技-工业级以太网交换机常见问题解析!
  7. [转载] 华中科技大学期刊分类办法
  8. java小白会有那些工作_Java小白找工作与学习的第二天
  9. 电脑版我的世界java_我的世界pc JAVA版
  10. URL编码与解码原理
  11. 计算机bios所以的英文翻译,bios界面翻译对照 主板BIOS界面全英文翻译介绍
  12. 利用Scrapy编写“1024网站种子吞噬爬虫”,送福利
  13. 微信视频压缩画质怎么办?微信发视频怎么不压缩画质
  14. Yolov5 最简推理代码
  15. 微生物所东秀珠组与北大深圳研究生院余珂组联合招聘启事
  16. 在Vue中使用flex布局 echarts多图标不能自适应缩放问题
  17. 微信小程序,一个有局限的类似 React Native 轮子
  18. OpenVINO2022.1+open_model_zoo例程的编译与使用
  19. MinGW-w64简介
  20. mysql最高安全级别双一_MySQL技术体系之核心参数

热门文章

  1. 无需可控文件的LFI-RCE
  2. manjaro装错驱动开机黑屏
  3. php v9最新漏洞,Phpcms v9漏洞分析
  4. python网页爬虫菜鸟教程_python菜鸟 想做一个简单的爬虫 求教程
  5. 如何设计存储分类,用来满足视频点播系统中大量内容分类和存储扩展的需求?
  6. Error type 三: Activity Class {.} dose not exist【解决方案】
  7. Power BI Desktop启动报错:调用的目标发生了异常
  8. chgrp r mysql_Linux中chgrp命令起什么作用呢?
  9. Python progress - 文本进度条
  10. 小学学校计算机生均比是多少,义务教育基本办学条件十项指标.doc