【Esper技术专题】带你进入事件驱动领域(内存计算、事件驱动、SQL支持)| 8月更文挑战

本文涉及的产品
云原生数据库 PolarDB MySQL 版,Serverless 5000PCU 100GB
简介: 【Esper技术专题】带你进入事件驱动领域(内存计算、事件驱动、SQL支持)| 8月更文挑战

【基本简介】


  • Esper是一个事件流处理(ESP)和事件关联引擎(CEP的,复杂事件处理)。
  • Esper的目标是针对实时事件驱动架构(EDA)
  • Esper监测到事件流中又符合条件的时间发生时,即可触发PlainOldJavaObjects(POJO)编写的自定义操作。


当数百万数量级的事件同时发生时,我们不可能使用普通的关系型数据库来存储和查询,Esper正是专为这样的大批量关联事件而设计的。


【Esper概念】


  • Esper提供一个定制的事件处理语言(EPL),允许的条件表达丰富的事件,相关性,可能跨越时间窗,从而减少开发工作需要设置一个系统,可以对复杂的情况作出反应。
  • Esper是一个轻量级的Java编写的内核是完全纳入任何Java进程,JEE应用服务器或基于Java的企业服务总线嵌入的。它使应用程序的过程中收到的消息或事件的大量快速发展。


介绍事件流和复杂事件信息是至关重要的作出明智的决定。


Esper,不得不说一下CEP。CEP即Complex Event Process,中文意思就是"复杂事件处理"。


听起来好像很复杂,实际上就是基于事件流进行数据处理,把要分析的数据抽象成事件,然后将数据发送到CEP引擎,引擎就会根据事件的输入和最初注册的处理模型,得到事件处理结果。




【CEP介绍】


Complex Event Processing, 复杂事件处理


事件(Event)一般情况下指的是一个系统中正在发生的事,事件可能发生在系统的各个层面上,它可以是某个动作,例如客户下单,发送消息,提交报告等,也可以是某种状态的改变,例如温度的变化,超时等等。


通过对这些事件进行分析,可以提取出其中有效的信息。 根据维基百科的定义,事件处理(Event processing)指的是跟踪系统中发生的事件,分析事件中的信息并从中得到某种结论。而复杂事件处理,则是结合多个事件源中的事件,从中推断出更加复杂的情况下的事件。


由此可见,CEP的目的包括:


  • (1)识别所需要的事件;
  • (2)快速地对这些事件进行处理。


通常情况下,我们想要利用CEP达到的目的是掌握当前的某种情况或者说状态,因此CEP感兴趣的不是事件本身给出的信息,而是通过这些信息所能推导出的某种结论,通过CEP,我们能够让这些事件变得有意义


要实现一个CEP引擎,需要考虑的事情包括:


  • (1)吞吐量;
  • (2)低延迟,从事件到达到事件被处理,不能有太大的延迟;
  • (3)复杂的逻辑处理,CEP需要能够对事件进行较为复杂的操作,例如,检测事件之间的相关性,过滤,加窗,连接等。

CEP是一种标准,Esper只是对这个标准的一种开源实现。除了Esper,很多大公司也有类似的商业软件,比如IBM,Sybase等等,听说巨贵无比。


CEP的一个重要特点就是他是一个内存计算工具和类SQL语句。内存计算可以说是一把双刃剑。


  • 好处自不必说,一个字:快!坏处也显而易见,数据有丢失的风险,而且还有容量的限制(实时计算其实并不受制于内存大小,而是得看如何对实时进行定义,也就是具体的业务来决定了)。
  • 所以如果业务不能容忍数据丢失,那么高可用方案就必须做好,不过Esper的高可用很不好做。

CEP的类SQL语句,可以理解为处理模型的定义与描述。这是运行在CEP引擎中的特殊语句,之所以叫他类SQL,是因为它和SQL确实很像,除了select,insert,delete,update,而且也有avg,count等函数。


所以对于会SQL的人来说,他的语法结构大致还是能猜出一二的。在Esper中,这个句子叫做EPL,即Event Process Language。作为Esper的核心内容。


定制的事件处理语言EPL,允许表达丰富的事件条件、关联性,也可跨越事件窗口,从而最大限度的减少为应对复杂情况而必须建立系统的开发难度。



【总结】


Esper是一个事件处理和复杂事件关联处理的java内核的轻量级引擎。对于大量事件的处理,能够用最短的时间做出反应,触发相应的操作。另外,为Esper量身定制的事件处理语言——类SQL语言,对于表达事件的条件以及关联关系的处理等非常方便。


事件流和复杂事件


一条一条的离散事件是没有意义的,事件流——一个无限的事件集合——可认为是一个滑动的窗口,进一步关联是非常有意义的,并用最小的延迟对事件做出反应,对有效行动和竞争优势是至关重要的。


事件流其实一个个离散的事件串接而成。现实中对于事件流的监控或者处理,比如股票信息等,需要实时性的计算其走势,以便能够及时的获取有价值数据。事件流在Esper中是一个滑动的窗口,对事件关联处理等至关重要。




Esper


关系型数据库或者基于消息的系统比如JMS,真的很难处理时间数据和实时查询。事实上,数据库需要一个明确的查询来返回有意义的数据,并且在数据放生变化时不适合推送数据。JMS系统是无状态的,需要开发人员自己实现这个时间和聚合的逻辑。相比之下,Esper提供了更高的抽象和智能,可以认为是数据库的倒置:不是存储数据,而是对存储的数据运行查询,Esper允许应用程序存储查询,并让数据运行通过。


当满足查询的条件发生时,Esper会做出实时的响应。执行模块是持续的,而不是只有在查询提交的时候。这个概念是EDA(事件驱动架构)的关键基础,在过去的10年,甚至更久都一直在积极的研究。然而,现实中对该系统重要性的认知最近才开始出现。


在Esper中,定制的EPL允许在引擎中注册查询。监听类(POJO类)会在事件满足EPL条件的时候由引擎进行调用。EPL能够表达复杂的匹配条件,包括事件窗口、事件流关联、过滤、聚合以及排序等。Esper statement也可以通过“followed by ” 即“->”条件从多个简单的事件中获取复杂事件。事件可以被描述成


JavaBean类、传统的java类、XML或者是Map,作为消息发布者,促进重用现有的系统。


【总结】在处理实时性的数据时,比如心跳监控、股票价格走势等,Esper相对于关系型数据库有天然的优势,Esper不需要对完成的数据的存储,便可以完成数据的实时查询处理,从这点看,更像是数据库的倒置——试想一下,数据库是先存储数据,通过编译解析SQL,完成已存储数据的查询,Esper则是先编译


EPL语句,形成一个过滤(或处理)层(或者网),实时过来的数据,通过这个过滤层完成有效事件的筛选或形成有效事件。Esper的事件处理语言——EPL,是类SQL语言,其select 语句、from语句、where语句以及group by 、having等,甚至包括大部分的聚合函数等,都和标准的SQL语言一致。在EPL规则的编写


上,对于有数据库开发经验的人来说,上手十分容易。




4、开发事件驱动应用


用Esper来开发事件驱动应用并不困难。大概有下面的几步:


  • 1> 通过分析业务域和定义探测的情景或者需要报告的信息,定义应用程序应该完成的功能或任务。
  • 2> 定义性能要求,特别是吞吐量和延迟。
  • 3> 确定从什么地方获取事件。
  • 4> 根据业务确定事件格式和事件内容。
  • 5> 设计导致复杂事件的事件关系。
  • 6> 事件源。
  • 7>  设计事件表示类型:java类、map、或XML等
  • 8> 定义EPL语句,用于匹配模式和流的处理。
  • 9> 比如,用CSV适配器作为事件模拟工具,测试检测场景,或产生加载加载事件。
  • 10> 在最终的环境上,测试吞吐量和延迟。



设计事件表示方式


在Esper当中,java类是一种简单、丰富且通用的事件表示方式。通过接口和超类,java类提供了继承性和多态性,通过一个对象graph,就可以表示一个复杂的业务域。Maps或XML也是事件表示的一种方式。



事件流分析


EPL语句从一个或者多个事件流中派生和聚合信息,加入或合并事件流,并将一个时间流的结果提供给后续的语句。


EPL在select语句和where语句的使用上,和SQL很相似。


不过EPL语句用事件流和views替换了数据库的表格。和SQL中表格相似,views定义了可用于查询和过滤的数据。Views可以表示为一个事件流上的一个窗口。


Views也可以排序事件、从事件属性获取统计数据、进行事件分组或者处理唯一的事件属性值。


下面的EPL语句用于计算股票事件过去30s的平均价格:


select avg(price) from StockTickEvent.win:time(30 sec) 
复制代码
复制代码

下面EPL返回的是前100条股票事件的平均值:

select symbol, avg(price) as averagePrice from StockTickEvent.win:length(100) group by symbol
复制代码
复制代码



下面的例子关联了两个事件流。


第一个事件流由欺诈告警事件组成,用于保存过去30s的事件信息。


第二个流则是withdrawal事件,用来保存过去30秒的事件。这两个流通过account 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
复制代码
复制代码





事件模式匹配

  Event patterns match when an event or multiple events occur that match the pattern's definition.

一个或多个事件发生时,事件模式会匹配定义的模式(很别扭啊⊙﹏⊙b)。模式也可以是基于时间的。模式匹配时通过状态机实现的。


模式表达式可以由连接了模式操作符的过滤器表达式组成。通过在圆括号中的嵌入表达式,可以实现更深的模式表达式嵌套。


5类操作符:


  ·控制模式探测器的创建和终止:every

    · 逻辑操作符:and、or、not

  · 操作事件顺序的时间操作符:-> (紧跟着发生的,followed by)

  · 过滤输出事件的where条件,引起模式探测器的终止:如,timer:within

  · 和观察其他事件一样,观察者也观察时间事件,如 timer:interval,  timer:at

下面是一些EPL的例子:

//模式匹配的是在接下来60秒钟IBM股票值大于80的所有事件
every StockTickEvent(symbol="IBM", price>80) where timer:within(60 seconds)
复制代码
复制代码
//每小时的第5分钟给出提醒:
every timer:at(5, *, *, *, *)
复制代码
复制代码
//当A事件发生时,如果后面跟的是B事件或C事件,则给出提醒(输出A事件)
A -> ( B or C )
复制代码
复制代码
//匹配的是每一个EventX,如果后跟EventY事件,并且其objectID和EventX的objectID一样,则给出提醒(输出a事件):
every a=EventX -> every b=EventY(objectID=a.objectID)
复制代码
复制代码





模式匹配和事件流分析结合使用


  当检测到事件序列(或没有事件发生)时,模式就会匹配。模式匹配的结果可以用于进一步的分析和处理。

  下面的模式监测的是 Status事件发生后的10s没有相同ID的status事件发生的场景。整个EPL语句进一步计算了所有发生的每个ID的事件总数。

select a.id, count(*) from pattern [ every a=Status -> (timer:interval(10 sec) and not Status(id=a.id)] group by id
复制代码
复制代码




命名窗口


命名窗口在引擎中是全局的数据窗口,其可以参与到很多的语句查询,并且可以被多个statement执行select、insert和delete操作。命名窗口和关系型数据库系统的表很相似。


通过下面的几步可以创建命名窗口:

create window AlertNamedWindow as (origin string, priority string, alarmNumber long)
复制代码
复制代码


当事件到达时,可以触发一个select、update或delete操作。下面是一个select应用,简单的统计数据窗口中的记录行总数:

on TriggerEvent select count(*) from AlertNamedWindow
复制代码
复制代码




匹配-识别模式匹配(Match-Recognize Pattern Matching)


匹配-识别模式是一个基于正则表达式的模式匹配语法,是建议列入SQL的标准语法。


下面的匹配-识别模式,探测的是可能出现在事件中的模式,这些事件通过命名窗口(如上声明)保存。这个模式查找的是两个紧跟的事件,即事件之间没有相同的origin。第一个事件必须有一个“high”优先级,第二个事件必须是“medium”优先级。


select * from AlertNamedWindow
  match_recognize (
    partition by origin
    measures a1.origin as origin, a1.alarmNumber as alarmNumber1, a2.alarmNumber as alarmNumber2
    pattern (a1 a2)
    define
      a1 as a1.priority = 'high',
      a2 as a2.priority = 'medium' 
)
复制代码
复制代码




变量(Variables)


变量是一个标量、对象或者事件值,可用于所有的statement,包括模式。变量可以用在EPL中任意位置的表达式中。


【总结】开发Esper应用时,事件类型建议采用Java类,对于事件信息的描述更为直观(参考Quick Start)。在具有复杂关系的事件设计中,不建议使用Map的方式(可参考Esper参考文档性能部分)。


在EPL设计时,根据业务需求,如果能通过标准的SQL语法完成的,尽量不要使用匹配模式,因为在运行时,需要对Pattern进行额外的解析,其规则较SQL复杂,性能上有少许损耗。


数据窗口的使用,能够使得Esper处理更为复杂的应用场景,比如与分布式缓存、静态数据的使用等。变量不难理解,不管是高级的开发语言如java、C/C++,还是脚本语言如ruby、JS等,都有变量的概念,其使用范围,仅限于当前的Esper引擎实例。



相关实践学习
使用PolarDB和ECS搭建门户网站
本场景主要介绍基于PolarDB和ECS实现搭建门户网站。
阿里云数据库产品家族及特性
阿里云智能数据库产品团队一直致力于不断健全产品体系,提升产品性能,打磨产品功能,从而帮助客户实现更加极致的弹性能力、具备更强的扩展能力、并利用云设施进一步降低企业成本。以云原生+分布式为核心技术抓手,打造以自研的在线事务型(OLTP)数据库Polar DB和在线分析型(OLAP)数据库Analytic DB为代表的新一代企业级云原生数据库产品体系, 结合NoSQL数据库、数据库生态工具、云原生智能化数据库管控平台,为阿里巴巴经济体以及各个行业的企业客户和开发者提供从公共云到混合云再到私有云的完整解决方案,提供基于云基础设施进行数据从处理、到存储、再到计算与分析的一体化解决方案。本节课带你了解阿里云数据库产品家族及特性。
相关文章
|
4月前
|
SQL 存储 大数据
【大数据技术Hadoop+Spark】Hive基础SQL语法DDL、DML、DQL讲解及演示(附SQL语句)
【大数据技术Hadoop+Spark】Hive基础SQL语法DDL、DML、DQL讲解及演示(附SQL语句)
78 0
|
4月前
|
SQL 分布式计算 数据库
【大数据技术Spark】Spark SQL操作Dataframe、读写MySQL、Hive数据库实战(附源码)
【大数据技术Spark】Spark SQL操作Dataframe、读写MySQL、Hive数据库实战(附源码)
102 0
|
4月前
|
SQL 分布式计算 大数据
【大数据技术Hadoop+Spark】Spark SQL、DataFrame、Dataset的讲解及操作演示(图文解释)
【大数据技术Hadoop+Spark】Spark SQL、DataFrame、Dataset的讲解及操作演示(图文解释)
55 0
|
29天前
|
缓存 Java C#
【JVM故障问题排查心得】「Java技术体系方向」Java虚拟机内存优化之虚拟机参数调优原理介绍(一)
【JVM故障问题排查心得】「Java技术体系方向」Java虚拟机内存优化之虚拟机参数调优原理介绍
80 0
|
29天前
|
SQL 关系型数据库 MySQL
【MySQL技术之旅】(7)总结和盘点优化方案系列之常用SQL的优化
【MySQL技术之旅】(7)总结和盘点优化方案系列之常用SQL的优化
42 1
|
1月前
|
缓存 算法 编译器
C/C++编译器内存优化技术:内存优化关注程序对内存的访问和使用,以提高内存访问速度和减少内存占用。
C/C++编译器内存优化技术:内存优化关注程序对内存的访问和使用,以提高内存访问速度和减少内存占用。
40 0
|
5月前
|
存储 缓存 安全
从原理到实践:掌握DPDK内存池技术(下)
从原理到实践:掌握DPDK内存池技术
|
5月前
|
存储 缓存 Unix
从原理到实践:掌握DPDK内存池技术(上)
从原理到实践:掌握DPDK内存池技术
|
2月前
|
SQL
14、sql注入绕过技术
14、sql注入绕过技术
28 0
|
2月前
|
SQL
小课堂 -- sql注入绕过技术
小课堂 -- sql注入绕过技术
86 0

热门文章

最新文章