EPL语法概述1、EPL 的标准语法骨架2、基础过滤与事件流选择SELECT FROM WHERE3、数据窗口语法Data Windows—— 流处理的物理边界4、分组与聚合GROUP BY HAVING5、高级时序控制输出频率限制OUTPUT6、核心杀手级语法模式匹配Pattern7、总结在 Esper 中EPLEvent Processing Language事件处理语言 是整个引擎的灵魂。它的语法虽然极度神似传统数据库的 SQL但其底层的执行逻辑却恰恰相反。传统 SQL 的本质是“数据静止查询在动”数据老老实实呆在磁盘里你发送一条 SQL 查一次而 EPL 的本质是“查询静止数据在流”EPL 规则像一张网一样死死挂在内存里数据像瀑布一样冲过去一旦命中立刻触发回调。1、EPL 的标准语法骨架一条完整的、复杂的 EPL 语句通常包含以下结构[Annotation]SELECTselect_listFROMevent_stream_expression[.win:window_spec][ASalias][WHEREsearch_conditions][GROUPBYgroup_by_expression][HAVINGhaving_conditions][OUTPUT output_spec]乍一看与 SQL 一模一样但请注意其中win:window_spec窗口 和OUTPUT输出控制 是传统 SQL 绝不可能存在的流处理核心特有语法。2、基础过滤与事件流选择SELECT FROM WHERE这是 EPL 最基本的形态用于从源源不断的事件流中筛选出符合条件的数据。示例 简单无状态过滤name(VIP-Order-Filter)selectorderId,price,buyerNamefromOrderEventwhereprice10000andregionCNname(...)注解。给这条 EPL 命名方便在 Java 代码中通过名字精准捞出对应的 EPStatement。OrderEvent这是你注册到引擎里的事件别名通常对应一个 Java Bean。执行逻辑没有任何内存缓存。每当一条 OrderEvent 流入只要价格大于 10000 且地区是 CN就立刻向外发射结果。3、数据窗口语法Data Windows—— 流处理的物理边界窗口主要分为两大流派滑动窗口Sliding 和 滚动/翻转窗口Tumbling/Batch。1. 滑动窗口数据有进有出位置不断向前推移win:time(时间大小)只保留最近一段时间内的数据。-- 统计最近 10 秒内流入的刷卡事件的总金额selectsum(amount)fromCardPayEvent.win:time(10sec)win:length(条数大小)只保留最近的固定 N 条数据。-- 统计最近 3 条温度数据的平均值selectavg(temperature)fromTempEvent.win:length(3)2. 滚动/翻转窗口攒满一批打包处理然后清空win:time_batch(时间周期)每隔固定时间倒出来统计一次。-- 每隔 1 分钟统计一次这 1 分钟内所有登录失败的用户数selectcount(*)fromLoginFailEvent.win:time_batch(1min)win:length_batch(条数)凑够固定条数再触发。-- 每积攒够 100 条日志打包输出一次日志级别分类统计selectlogLevel,count(*)fromLogEvent.win:length_batch(100)groupbylogLevel4、分组与聚合GROUP BY HAVING当流数据配合窗口使用时GROUP BY 的威力才真正显现。selectdeviceId,max(value)asmaxValfromSensorEvent.win:time(5min)groupbydeviceIdhavingmax(value)100内存运作Esper 会在内存里为每一个不同的 deviceId 维护一个长达 5 分钟的滑动窗口。触发时机只要任何一个设备的 5 分钟内最大值超过了 100就会向外发射。注意这里的 group by 会隐式占用内存。如果设备源源不断且几万个设备以后再也不发数据了需要配合 Context上下文来及时释放过期设备的内存否则会导致内存泄漏。5、高级时序控制输出频率限制OUTPUT在传统 SQL 中算完了直接一把梭给出来。但流处理不行。比如“最近 1 小时内”每流过一条数据滑动窗口的值都在变如果你绑定了监听器监听器一秒钟会被轰炸几万次。OUTPUT关键字就是用来给输出结果做限流和定时定量外发的。selectsymbol,avg(price)fromStockTick.win:time(1hour)groupbysymbol outputlastevery5secoutput last every 5 sec每隔 5 秒钟才把过去 1 小时滑动窗口算出来的最后一条最新一条统计结果发送给 Java 监听器。中间那 5 秒内产生的无数动态变化直接在内存里悄悄更新不轰炸外部系统。常用策略output first只要周期内的第一条、output last只要最新的、output all把这 5 秒内产生的所有中间结果打包一起发。6、核心杀手级语法模式匹配Pattern这是 EPL 最难、但也是最强悍的地方。它不用from Event.win:的传统格式而是使用from pattern [...]语法专门用来抓取“先发生 A接着发生 B中间不能发生 C”这种因果和时序关系。核心符号-跟随操作符A 发生后接着发生 B。every循环修饰符。如果没有 every该规则触发一次后就会在内存里销毁。timer:within(时间)时间沙漏限制。示例电商防刷频次因果用户userId在一分钟内连续 3 次登录失败接着立刻发生了一笔大额消费。selecta.userId,b.amountfrompattern[every(aLoginEvent(successfalse)-LoginEvent(userIda.userId,successfalse)-LoginEvent(userIda.userId,successfalse)-bOrderEvent(userIda.userId,amount5000))wheretimer:within(1min)]示例物联网故障检测状态缺失检查传感器启动了StatusSTART但在接下来的 10 秒钟内没有收到任何心跳上报StatusPING。解读and not配合timer:interval可以在指定时间内一旦没有等到预期事件时精准触发超时告警。7、总结Getter 强依赖EPL 里写 select name底层的 Java 类必须有标准的 public String getName()。避免无边界的 GROUP BY千万别在没有加 win:time 窗口的流上直接用 group by。这会导致 Esper 认为你要把从开机到关机所有的历史数据都按 Key 存在内存里用不了几天 JVM 就会直接 OutOfMemoryError。Pattern 与普通 EPL 的区别普通的 EPLfrom MyEvent.win:time侧重于数据量的统计和计算算平均值、最大值。Pattern EPLfrom pattern [...]侧重于时序的触发和警报捕捉特定行为轨迹。
Esper——EPL语法概述
EPL语法概述1、EPL 的标准语法骨架2、基础过滤与事件流选择SELECT FROM WHERE3、数据窗口语法Data Windows—— 流处理的物理边界4、分组与聚合GROUP BY HAVING5、高级时序控制输出频率限制OUTPUT6、核心杀手级语法模式匹配Pattern7、总结在 Esper 中EPLEvent Processing Language事件处理语言 是整个引擎的灵魂。它的语法虽然极度神似传统数据库的 SQL但其底层的执行逻辑却恰恰相反。传统 SQL 的本质是“数据静止查询在动”数据老老实实呆在磁盘里你发送一条 SQL 查一次而 EPL 的本质是“查询静止数据在流”EPL 规则像一张网一样死死挂在内存里数据像瀑布一样冲过去一旦命中立刻触发回调。1、EPL 的标准语法骨架一条完整的、复杂的 EPL 语句通常包含以下结构[Annotation]SELECTselect_listFROMevent_stream_expression[.win:window_spec][ASalias][WHEREsearch_conditions][GROUPBYgroup_by_expression][HAVINGhaving_conditions][OUTPUT output_spec]乍一看与 SQL 一模一样但请注意其中win:window_spec窗口 和OUTPUT输出控制 是传统 SQL 绝不可能存在的流处理核心特有语法。2、基础过滤与事件流选择SELECT FROM WHERE这是 EPL 最基本的形态用于从源源不断的事件流中筛选出符合条件的数据。示例 简单无状态过滤name(VIP-Order-Filter)selectorderId,price,buyerNamefromOrderEventwhereprice10000andregionCNname(...)注解。给这条 EPL 命名方便在 Java 代码中通过名字精准捞出对应的 EPStatement。OrderEvent这是你注册到引擎里的事件别名通常对应一个 Java Bean。执行逻辑没有任何内存缓存。每当一条 OrderEvent 流入只要价格大于 10000 且地区是 CN就立刻向外发射结果。3、数据窗口语法Data Windows—— 流处理的物理边界窗口主要分为两大流派滑动窗口Sliding 和 滚动/翻转窗口Tumbling/Batch。1. 滑动窗口数据有进有出位置不断向前推移win:time(时间大小)只保留最近一段时间内的数据。-- 统计最近 10 秒内流入的刷卡事件的总金额selectsum(amount)fromCardPayEvent.win:time(10sec)win:length(条数大小)只保留最近的固定 N 条数据。-- 统计最近 3 条温度数据的平均值selectavg(temperature)fromTempEvent.win:length(3)2. 滚动/翻转窗口攒满一批打包处理然后清空win:time_batch(时间周期)每隔固定时间倒出来统计一次。-- 每隔 1 分钟统计一次这 1 分钟内所有登录失败的用户数selectcount(*)fromLoginFailEvent.win:time_batch(1min)win:length_batch(条数)凑够固定条数再触发。-- 每积攒够 100 条日志打包输出一次日志级别分类统计selectlogLevel,count(*)fromLogEvent.win:length_batch(100)groupbylogLevel4、分组与聚合GROUP BY HAVING当流数据配合窗口使用时GROUP BY 的威力才真正显现。selectdeviceId,max(value)asmaxValfromSensorEvent.win:time(5min)groupbydeviceIdhavingmax(value)100内存运作Esper 会在内存里为每一个不同的 deviceId 维护一个长达 5 分钟的滑动窗口。触发时机只要任何一个设备的 5 分钟内最大值超过了 100就会向外发射。注意这里的 group by 会隐式占用内存。如果设备源源不断且几万个设备以后再也不发数据了需要配合 Context上下文来及时释放过期设备的内存否则会导致内存泄漏。5、高级时序控制输出频率限制OUTPUT在传统 SQL 中算完了直接一把梭给出来。但流处理不行。比如“最近 1 小时内”每流过一条数据滑动窗口的值都在变如果你绑定了监听器监听器一秒钟会被轰炸几万次。OUTPUT关键字就是用来给输出结果做限流和定时定量外发的。selectsymbol,avg(price)fromStockTick.win:time(1hour)groupbysymbol outputlastevery5secoutput last every 5 sec每隔 5 秒钟才把过去 1 小时滑动窗口算出来的最后一条最新一条统计结果发送给 Java 监听器。中间那 5 秒内产生的无数动态变化直接在内存里悄悄更新不轰炸外部系统。常用策略output first只要周期内的第一条、output last只要最新的、output all把这 5 秒内产生的所有中间结果打包一起发。6、核心杀手级语法模式匹配Pattern这是 EPL 最难、但也是最强悍的地方。它不用from Event.win:的传统格式而是使用from pattern [...]语法专门用来抓取“先发生 A接着发生 B中间不能发生 C”这种因果和时序关系。核心符号-跟随操作符A 发生后接着发生 B。every循环修饰符。如果没有 every该规则触发一次后就会在内存里销毁。timer:within(时间)时间沙漏限制。示例电商防刷频次因果用户userId在一分钟内连续 3 次登录失败接着立刻发生了一笔大额消费。selecta.userId,b.amountfrompattern[every(aLoginEvent(successfalse)-LoginEvent(userIda.userId,successfalse)-LoginEvent(userIda.userId,successfalse)-bOrderEvent(userIda.userId,amount5000))wheretimer:within(1min)]示例物联网故障检测状态缺失检查传感器启动了StatusSTART但在接下来的 10 秒钟内没有收到任何心跳上报StatusPING。解读and not配合timer:interval可以在指定时间内一旦没有等到预期事件时精准触发超时告警。7、总结Getter 强依赖EPL 里写 select name底层的 Java 类必须有标准的 public String getName()。避免无边界的 GROUP BY千万别在没有加 win:time 窗口的流上直接用 group by。这会导致 Esper 认为你要把从开机到关机所有的历史数据都按 Key 存在内存里用不了几天 JVM 就会直接 OutOfMemoryError。Pattern 与普通 EPL 的区别普通的 EPLfrom MyEvent.win:time侧重于数据量的统计和计算算平均值、最大值。Pattern EPLfrom pattern [...]侧重于时序的触发和警报捕捉特定行为轨迹。