CEP即Complex Event Processing复杂事件处理,它可以让你在无限事件流中检测出特定的事件模型。新版本的SQL标准支持在SQL中的模式识别(Row Pattern Recognition in SQL),它允许Flink使用MATCH_RECOGNIZE子句融合CEP和SQL API,以便在SQL中进行复杂事件处理。
二、应用场景
目标:从有序的简单事件流中发现一些高阶特征
输入:一个或多个简单事件构成的事件流
处理:识别简单事件之间的内在联系,多个符合一定规则的简单事件构成复杂事件
输出:满足规则的复杂事件
CEP处理:
每个 MATCH_RECOGNIZE 查询都包含以下子句:
PARTITION BY - 定义表的逻辑分区;类似于 GROUP BY *** 作。 ORDER BY - 指定传入行的排序方式;这是必须的,因为模式依赖于顺序。 MEASURES - 定义子句的输出;类似于 SELECT 子句。 ONE ROW PER MATCH - 输出方式,定义每个匹配项应产生多少行。对于SQL API只支持ONE ROW PER MATCH,对于Stream API还支持ALL ROWS PER MATCH。 AFTER MATCH SKIP - 指定下一个匹配的开始位置;这也是控制单个事件可以属于多少个不同匹配项的方法。 PATTERN - 允许使用类似于 正则表达式 的语法构造搜索的模式。 DEFINE - 本部分定义了模式变量必须满足的条件。
注意 目前,MATCH_RECOGNIZE 子句只能应用于追加表。此外,它也总是生成一个追加表。
四、进阶 4.1、贪婪量词和勉强量词每一个量词可以是 贪婪(默认行为)的或者 勉强 的。贪婪的量词尝试匹配尽可能多的行,而勉强的量词则尝试匹配尽可能少的行。
在SQL API里有以下语法规则:
所谓的贪婪就是*和+,所谓的勉强就是?
例如:
PATTERN (A B* C) WITHIN INTERVAL '2' MINUTE DEFINE A AS A.num>10, B AS B.num<15, C AS C.num>12
其中事件B的匹配是贪婪的,数据集为:
输出结果为:
贪婪匹配的结果是,B事件会尽力匹配更多的行,因此所有小于15的都被判断为B事件了,即12,13,14均为B事件。那么相应勉强匹配是:
PATTERN (A B*? C) WITHIN INTERVAL '2' MINUTE DEFINE A AS A.num>10, B AS B.num<15, C AS C.num>12
对应的输出结果为:
前面提到,像 (A B) 这样的模式意味着 A 和 B 之间的连接是严格的。因此,在它们之间不能存在没有映射到 A 或 B 的行,也就是说这样的模式是严格近邻的。其实在CEP Stream API里,是支持不连续的,也就是宽松近邻,如图所示:
在SQL里是没有宽松近邻概念的,模式种的事件必须严格按照顺序排布。那么SQL就没有办法处理宽松近邻场景了吗?答案是否定的,我们可以通过中间事件结合贪婪量词实现。事实上在上面的例子种已经涉及,即:
PATTERN (A B* C) WITHIN INTERVAL '2' MINUTE DEFINE A AS A.num>10, B AS B.num<15, C AS C.num>124.3 循环匹配
假设在宽松近邻场景下,有以下数据集合:
可以结合AFTER MATCH跳转语法实现
使用SKIP TO NEXT ROW,可以在匹配了一个模式后,继续匹配项的第一个成员的下一行开始匹配,也就是循环匹配。
ONE ROW PER MATCH AFTER MATCH SKIP TO NEXT ROW PATTERN (A X* C) WITHIN INTERVAL '2' MINUTE DEFINE A AS A.num<3, C AS C.num>7, X AS NOT X.num>7
测试数据集:
输出结果:
通过SKIP TO NEXT ROW实现了循环匹配,但是却无法对结尾事件做循环匹配,因为语法不支持在结尾事件中使用贪婪或勉强量词。即无法应对这样的场景:
这种场景是否有解决方案呢?当你遇到了这种场景,首先思考应该是否真的存在?也许可以通过合理的规则制订避免,如果实在无法避免,这可能就是CEP无法解决的组合。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)