Ohhnews

分类导航

$ cd ..
DZone Java原文

Apache Flink 复杂事件处理(CEP):定义及何时(不)使用它

#apache flink#复杂事件处理#流处理#模式匹配#实时分析

https://dzone.com/articles/apache-flink-1大多数使用 Apache Flink 的团队都会想到流处理:过滤事件、聚合值、丰富记录、连接流。这覆盖了大多数实时数据问题。但有一类特定问题,流处理处理得很差:检测跨时间的有意义事件序列。这条特定的事件链是否按这个顺序、在这个时间窗口内发生了?复杂事件处理(CEP)正是为此设计的工具,并且它的工作方式与流处理有根本不同。CEP 是 Apache Flink 的内置能力,以开源形式提供,并且可以部署到旧有专有平台永远无法达到的规模。然而,它仍然未被充分利用且被误解。本文是一份实用指南,介绍 CEP 是什么、何时使用、Flink 如何实现它,以及它如何融入现代数据架构,包括 agentic AI,后者在配套文章中有深入介绍。

理解 CEP 最简单的方式是将其与常规流处理进行对比。流处理持续处理事件,一次一个或在窗口中处理。它回答诸如:过去五分钟的平均交易金额是多少?该用户在过去一小时内进行了多少次登录尝试?这些是有状态的实时计算,但它们操作的是单个事件或聚合。它们不寻找序列。CEP 回答的是另一类问题:事件 A 是否发生,随后在 30 秒内发生事件 B,但之前 10 分钟内没有发生事件 C?它在定义的时间窗口内按定义的顺序检测跨多个事件的模式。可以把它想象成应用于事件流而非文本字符串的正则表达式引擎。你定义一次模式。Flink 会持续根据每个活动模式评估每一个到达的事件。一旦找到完整匹配,就发出结果。

[LOADING...]

架构上的含义很重大。在传统数据库中,查询针对已存储的数据运行。在 CEP 中,数据针对已存储的查询运行。不匹配任何活动模式的事件会立即被丢弃。这使得 CEP 在高流量下极其高效,因为无关数据永远不会累积。有一个区别值得明确:CEP 使用静态的、预定义的模式。你需要准确指定要寻找的序列。当业务逻辑已知且确定时,这是正确的做法。另一种选择是动态异常检测,其中带有统计或 ML 函数的流处理会从历史数据中建立基线,并在不需要显式规则的情况下标记偏差。两种方法都解决实际问题,而且都运行在 Flink 上。选择取决于你是否知道自己在寻找的模式。更多内容见“何时不应使用 Flink CEP”一节。

缺失事件问题

最有价值且最不被理解的 CEP 用例之一值得单独用一节来讲:检测“没有发生”的事件。这会让大多数从业者感到意外,因为本能上会把事件处理想成对到达的事件做出反应。但一些最重要的业务信号其实是“缺失”。一个本应每 60 秒发出一次心跳的机器传感器沉默了。一个本应在发货事件后四小时内到达的交付确认从未到达。一个本应完成交易链的支付结算缺失了。在每种情况下,业务都需要立即知道,而不是等人注意到缺口之后。

面对这个问题时,本能反应是求助于 CEP Pattern API 或 MATCH_RECOGNIZE。但对于缺失事件检测,Flink SQL 中的 LEFT JOIN 通常是更合适、更节省内存的方法。查询会问:给我所有事件 A 到达、但预期事件 B 在时间窗口内从未跟随的情况。就状态管理而言,这比把“缺失”表达为否定模式更清晰、更可预测。

这里的内存管理比大多数团队预期的更重要。Flink 会为其正在评估的每个活动模式维护状态。一个具有七天回溯窗口、跨高基数键的模式,所需内存远多于 60 分钟窗口的模式。始终在模式定义中使用 WITHIN 子句来显式限定时间窗口。如果不这样做,在长时间运行的流式作业中状态会无界增长,这是生产环境 Flink CEP 部署中最常见的运维问题之一。

供应商格局:从传统专有平台到 Apache Flink

在查看供应商之前,有一个区别值得澄清:CEP 市场和流处理市场在历史上是分开的类别,拥有各自独立的产品。下图说明了原因:流处理在每个窗口都输出;CEP 仅在确认完整模式匹配时输出。理解这种分离,既能解释旧市场的碎片化,也能解释为什么 Flink 能在同一个平台中处理两者,代表着如此重大的转变。

TIBCO:BusinessEvents(CEP)与 StreamBase(流处理)

作为那个时代占主导地位的中间件供应商,TIBCO 有两个独立产品。BusinessEvents 于 2004 年推出,是一个纯 CEP 引擎:基于规则的推理、有状态事件关联,尤其在电信和保险领域表现强劲。StreamBase 于 2013 年被收购,是一个完全独立的纯流处理平台,专为高吞吐金融交易设计。

Software AG:Apama(CEP 与流处理合二为一)

Software AG Apama 是值得注意的例外:单一平台在一个产品中结合了 CEP 和事件流处理。这是它相对于 TIBCO 的竞争优势,后者需要两个独立工具才能覆盖同样的范围。Apama 在资本市场和算法交易领域表现强劲,并直接在金融服务细分市场竞争。Software AG 于 2011 年收购了它。

IBM 与 Oracle:细分领域采用

IBM WebSphere Business Events 和 Oracle CEP 完善了市场,但两者都未能在其核心垂直领域达到 TIBCO 或 Apama 所建立的采用深度。上述所有平台如今实际上都已成为遗留系统。它们价格昂贵、需要深厚的专家知识,并且无法扩展到现代架构所要求的事件量。Apache Flink 作为一个开源框架出现,将所有这些平台的核心能力吸收到一个统一平台中,以更大的规模和更低的成本运行。

开源:Apache Flink

Apache Flink 的基础仍然是开源的。可自管理、功能完整,并且是所有商业发行版构建的基础。对于拥有强大工程能力、希望获得最大控制和灵活性的团队来说,这是正确的选择。

IBM:Confluent Cloud 与 Confluent Platform

Confluent 在 Confluent Cloud 上以完全托管的无服务器服务形式提供 Flink,也通过 Confluent Platform 提供自管理发行版,两者都与 Apache Kafka 紧密集成。通过 Flink SQL 中的 MATCH_RECOGNIZE 实现 CEP 是两者的一流能力。Confluent Platform 还支持 DataStream API,使本地或私有云环境中的团队能够使用完整的编程式 CEP 功能集。Confluent 最近被 IBM 收购,此举将合并后的产品组合定位为 IBM 混合云战略的核心支柱:企业可以将 Confluent Cloud 作为完全托管服务运行,也可以在本地和私有云中部署 Confluent Platform,两者背后都有 IBM 的企业覆盖和支持。

Ververica:VERA 引擎

Ververica 由 Apache Flink 的原始创建者创立,提供 VERA 引擎。VERA 采用开放核心模式:与开源 Apache Flink 100% 兼容,并在其上提供专有性能优化。关键能力包括在不重启的情况下更新运行中作业的模式匹配规则、Gemini 状态存储引擎(它用云原生替代方案取代标准 RocksDB 后端,提供显著更快的快照)、计算存储分离,以及流式连接优化——对于苛刻工作负载,性能最高可达原生 Apache Flink 的两倍。Ververica 有三种部署模式:通过 Ververica Platform 在本地自管理、在 Ververica 公有云上完全托管,以及 BYOC(由 Ververica 在客户自己的云基础设施上管理平台)。托管云产品提供按量付费定价,按每计算单元每小时计费,或通过预留容量获得可预测定价。从缩容到零的意义上说,它并非完全无服务器,因此更适合具有稳定、连续工作负载的团队,而不是高度可变或间歇性处理模式的团队。

Amazon:Apache Flink 托管服务

Amazon Managed Service for Apache Flink 是 AWS 的完全托管 Flink 产品,对于已经在 AWS 基础设施上运行的组织来说是自然选择。该服务处理集群配置、自动扩缩容、检查点和多可用区可用性,并支持 Java、Python 和 SQL API,包括用于 CEP 用例的 MATCH_RECOGNIZE。关于“完全托管”定位的一个重要警告:与 Amazon MSK 一样,该服务并非真正无服务器。计费基于分配的 KPU(计算单元),而不是实际消耗,这意味着无论你的作业是否正在积极处理数据,你都要为预置容量付费。这与让许多 MSK 用户措手不及的营销差距相同。深度投入 AWS 技术栈、希望使用 Flink 而不管理集群基础设施的团队会觉得它是一个合理选择。那些需要基于消耗、完全托管且具有更深入 CEP 和 SQL 能力的平台的人,会发现 Confluent Cloud 或 Ververica 是更强的选择。有关数据流供应商格局的完整地图,包括部署模型和采用排名,2026 年数据流格局 是参考。

Flink 如何实现 CEP

Flink 提供两种互补的 CEP 方法。正确的选择取决于模式复杂性和团队的技术画像。关于发行版覆盖范围的一个重要说明:通过 DataStream API 使用的 Pattern API 在自管理 Apache Flink、Confluent Platform 和 Ververica 中可用,但在 Confluent Cloud 中不可用,后者仅通过 SQL 和 Table API 暴露 Flink。对于 Confluent Cloud 上的团队,MATCH_RECOGNIZE 是可用的 CEP 接口。下图在深入每种方法的技术细节之前,先一览核心概念。

通过 DataStream API 使用 Pattern API

编程式方法,适用于 Java 和 Python。你定义一个 Pattern 对象,指定要检测的事件序列,用运算符连接条件:.next() 用于严格连续性,即事件必须紧接着发生;.followedBy() 用于非严格连续性,即中间可以出现其他事件;.within() 用于对整个模式施加时间约束。将 Pattern 应用于 DataStream 以创建 PatternStream,再使用 PatternProcessFunction 从中提取匹配。这提供了对 CEP 能力最完整的访问,以及对复杂逻辑最大的灵活性。代价是 DataStream 作业需要更强的工程技能,并且随着复杂性增长可能变得难以维护。

通过 SQL 和 Table API 使用 MATCH_RECOGNIZE

SQL 方法基于 2016 年 12 月的 ISO 标准,自 Flink 1.7 版起可用。在底层,它使用与编程式 API 相同的 FlinkCEP 库。PARTITION BY 处理按实体的模式匹配,ORDER BY 确保正确的事件排序,PATTERN 使用正则表达式风格语法定义序列,DEFINE 将事件映射到模式变量。Flink 添加了非标准的 WITHIN 子句用于时间有界模式,这对生产环境的内存管理至关重要。SQL 方法可被更广泛的开发者、数据工程师和分析师使用。相对于完整 Pattern API,它的局限性在实践中是一种有用的约束:它们防止模式变得过于复杂而无法调试或维护。对于大多数业务级 CEP 需求,MATCH_RECOGNIZE 已经足够。

UI/UX 鸿沟:CEP 在很大程度上仍是一门工程学科

这是一个大多数 Flink CEP 文章都会跳过的坦诚局限,值得直接讨论。

模式编写是一项工程任务

在 Apache Flink 中编写模式从根本上说是一项工程任务。用 Java 或 Python 编写 DataStream API 代码需要开发人员。编写 MATCH_RECOGNIZE SQL 显著降低了门槛,但仍然假定熟悉 SQL 语法、事件时间语义以及流式模式匹配的特定约束。欺诈运营分析师、供应链经理或合规官无法在没有技术支持的情况下走到 Flink 集群前定义自己的检测规则。这在 CEP 世界中并不总是被接受的常态。TIBCO BusinessEvents 附带了可视化规则编辑器和决策表支持,使业务分析师无需工程参与即可编写和维护 CEP 规则。Apama 有一个图形化开发工作室。这些可视化界面是专有平台的真正优势,使最了解业务模式的领域专家能够直接编码,而无需经过工程工单队列。如今,开源 Flink 生态系统没有成熟的等价物。权衡是真实存在的,但并不完全是负面的:基于工程的 CEP 比可视化规则编辑器更强大、更灵活、更可测试,并且在大规模下更易维护,后者往往产生难以版本控制或审计的不透明逻辑。但它确实将采用门槛置于开发人员可用性之后,并在业务规则需要快速变更时造成瓶颈。

GenAI 正在部分弥合这一鸿沟

这一鸿沟正开始被部分弥合,途径与可视化工具不同。当前的 LLM 能够根据模式的自然语言描述生成正确的 MATCH_RECOGNIZE SQL。一位欺诈分析师描述“标记任何在 10 分钟内跨不同商户进行超过三笔 500 欧元以上交易的用户”,今天就可以从具备代码能力的 LLM 获得可用的 SQL 模式。这降低了可用 SQL 表达的模式的门槛,并为非工程师提供了一条实用路径,可以先制作检测逻辑原型,再交给工程团队审查和加固。限制同样真实。为复杂有状态模式生成的 DataStream API 代码在接近生产环境之前仍然需要工程审查。LLM 可以生成语法正确的 Flink 代码,但其中包含时间语义、状态处理或水位线行为方面的细微逻辑错误,如果没有深厚的 Flink 专业知识就不明显。对于任务关键型 CEP 逻辑,今天在没有人工审查的情况下生成并部署是不安全的。前瞻性的图景是,GenAI 将减少但不会消除对工程的依赖。使用定义良好、可用 SQL 表达模式的业务分析师和领域专家,将越来越多地通过自然语言界面获得服务,无论这些界面是嵌入 Confluent Cloud、Ververica 等平台,还是构建在 Flink 之上的第三方工具。涉及自定义 DataStream 算子、迭代条件或深度有状态逻辑的复杂模式工程,在可预见的未来仍将是一门开发者学科。正确的平台架构会同时考虑这两类人群:为业务用户暴露简单模式编写的抽象层,同时为需要的情况提供完整的工程级访问。

Flink CEP 行业用例

CEP 不是小众能力。以下用例代表了顺序模式检测能够带来通用流处理无法复制的业务价值的行业。

金融服务:欺诈检测

支付欺诈是全球生产环境中最成熟的 CEP 应用。现代欺诈几乎从来不是单个可疑事件。它是一条链:一张卡在柏林使用,两分钟后在伦敦尝试非接触式支付,紧接着是一笔高价值在线交易。CEP 在该序列完成的瞬间检测到它,计算地点之间的旅行时间在物理上是否可能,并在资金转移之前触发升级认证或账户冻结。更复杂的模式会串联五个或更多事件:快速卡枚举、跨渠道速度检查、账户接管序列。在不重启的情况下更新运行中作业的检测规则,在这一领域尤其有价值。欺诈模式会随着攻击者行为持续演变,而缩短从识别新攻击模式到部署检测规则之间的窗口,是一项直接的业务影响衡量指标。

制造业与 IoT:预测性维护

一台即将故障的机器不会突然故障。它会在故障前的一段时间发出多传感器特征:轻微的温升,然后是振动频率增加,接着是压力偏差。单传感器阈值警报要么完全错过该模式,要么产生太多误报而无法采取行动。CEP 能可靠地检测完整的多事件特征,并在仍有时间干预时触发维护工作流,将被动维护转变为预测性维护。基于 Apache Kafka 和 Apache Flink 的事件驱动架构已经在汽车和工业制造环境中投入生产,用于实时运营智能。基于 CEP 的预测性维护是建立在该现有流式基础之上的自然且高价值的应用层,将顺序模式检测应用于已经在流动的传感器流。

供应链与 ERP:流程监控

来自 SAP 和其他 ERP 系统、B2B 集成平台以及 EDI 网络的业务流程事件,形成了一条代表企业运营状态的连续流。一个生产订单在其生命周期中移动,会在每个阶段生成事件:订单创建、库存检查、生产开始、质量检验、货物发运。在 B2B 场景中,同样的逻辑跨贸易伙伴边界适用:采购订单触发预期的 EDI 消息序列,包括订单确认、提前发货通知和发票。如果任何步骤被跳过、延迟超过 SLA 或顺序错误,下游业务影响都是真实的,无论事件源自企业内部还是外部伙伴。CEP 实时监控整个流程流,同时跨越数千个并发订单和贸易伙伴交易。一旦单个订单或 EDI 交换偏离其预期序列,就会向下游消费者发布结构化警报,并触发相应工作流。这比在偏差发生 24 小时后才呈现出来的批处理报告具有绝对更高的价值,因为那时干预窗口已经关闭。

电信:网络与欺诈监控

电信是最早的 CEP 行业之一,并且仍然是最契合的行业之一。网络入侵检测、跨数百万同时连接的 SLA 违规监控,以及针对订阅欺诈的顺序通话详单分析,都精确匹配 CEP 模式。高事件量、严格延迟要求,以及欺诈和故障模式的顺序性质,使这一领域成为 CEP 始终能够交付更简单流处理无法复制的价值的领域。

电子商务:客户旅程检测

顺序行为模式正是 Flink SQL 中 MATCH_RECOGNIZE 特别擅长的领域,因为这些模式可以用贴近业务领域的清晰 SQL 逻辑表达。一个曾持有高级订阅、续订两次、然后降级到基础的客户,是一个流失风险信号。一个在一周内四次访问同一产品页面但没有购买的用户,是一个转化机会。这些模式在 MATCH_RECOGNIZE 中表达起来很直接,并且可以由分析师编写和维护,无需深厚的 DataStream API 专业知识。输出会馈送到实时个性化引擎、留存工作流触发器或转化活动系统。

何时不应使用 Flink CEP

对于正确的问题,CEP 是一个强大的工具。对于错误的问题,它只会增加运维复杂性而没有收益。有三种情况你应该选择其他方案:

模式未定义或过于动态,无法显式指定。如果你不知道自己在寻找什么序列,或者相关模式的变化速度超过规则编写和部署的速度,那么运行在 Flink 流处理能力上的基于 ML 的异常检测是更好的方法。让模型从历史数据中学习正常行为是什么样子,并标记统计偏差,而不是试图预先枚举所有可能的坏模式。CEP 和 ML 异常检测是互补的:CEP 用于已知模式,ML 用于未知模式,两者都运行在同一个 Flink 平台上,并馈送到相同的下游系统。

问题实际上不需要顺序模式检测。如果模式可以表达为窗口聚合,而不是严格的事件序列,那么标准的 Flink 窗口流处理查询比 CEP 作业更简单、更便宜、更易维护。例如,10 分钟窗口内超过五次登录失败,就是一个时间窗口内的计数。除非特定事件类型的顺序和交错很重要,否则它不需要 CEP。CEP 的价值特别体现在序列和顺序是模式重要性的一部分时。如果不是,Flink SQL 中的滚动或滑动窗口可以干净地处理它,而无需 CEP 状态机的开销。而如果业务操作可以等待计划报告或夜间批处理作业,那就根本不要构建流式架构。

回溯窗口相对于事件量来说长得不切实际。一个需要在七天的高基数事件数据中跟踪状态的模式,会消耗大量 Flink 集群内存。如果时间窗口非常长,并且事件量和键基数都很高,状态管理成本可能超过收益。要么使用 WITHIN 子句更积极地限制窗口,要么通过上游预聚合降低键基数,要么重新考虑批处理或 lambda 架构是否更适合该特定模式。

Flink CEP 参考架构与最佳实践

下面的参考架构展示了全貌:源系统馈送到事件摄取层,Flink CEP 作为模式检测器,下游消费者独立地对结构化输出做出反应。以下最佳实践直接源自该架构以及跨行业的生产部署。

保持模式聚焦,并且始终使用 WITHIN 对其进行限定。每个活动模式都会消耗与其复杂性和时间窗口成比例的 Flink 状态。从捕获业务意图的最简单模式开始。在每个模式定义中无一例外地添加 WITHIN 子句。无法剪枝的状态会在生产环境中引发运维问题,而且往往是在负载下难以诊断的方式。

通过下游消费者将检测与响应解耦。CEP 作业的输出应该是发布到 Kafka 主题、消息代理或架构所使用的任何下游系统的结构化事件,而不是嵌入作业本身的直接操作或 API 调用。下游消费者独立做出反应:告警系统、工作流引擎、AI 代理。这使 CEP 作业更简单、更稳定,允许多个消费者独立地对同一信号做出反应,并让响应逻辑无需触及检测逻辑即可演进。这是生产 CEP 部署最重要的架构原则。

避免单体式 Flink 作业。一个将模式检测、丰富、响应逻辑和下游路由结合在一起的大型作业是一种反模式。一个同时调用外部风险评分 API、写入数据库并发送通知的欺诈检测作业做了太多事情。当任何一个组件需要变更或失败时,整个作业都会受到影响。将关注点分离为聚焦的作业:一个作业负责 CEP 检测,另一个负责丰富,第三个负责 AI 推理。每个作业做好一件事,并且可以独立更新、扩展和调试。

CEP 未被充分利用、实用且比以往更相关

决策框架很简单。当你知道模式并需要实时检测它时,CEP 是正确的工具。当顺序无关紧要时,窗口流处理更简单。当模式过于动态而无法显式定义时,基于 ML 的异常检测是正确的工具。这三种方法互补,并运行在同一个 Flink 平台上。

传统 CEP 市场已经消失。通过 Confluent(IBM)、Ververica 和 Amazon 交付的 Apache Flink,已经以那些平台永远无法达到的规模和经济性吸收了它们所提供的一切。剩下的鸿沟是 UI/UX 障碍,GenAI 正在开始为可用 SQL 表达的模式缩小这一障碍,但尚未为复杂逻辑消除它。

检测模式只是问题的一半。另一半是接下来发生什么:哪个系统采取行动,带着什么上下文,以及拥有多少自主权。后续文章正好涵盖这一点:Flink CEP 如何连接到 Agentic AI 架构,以及为什么 CEP 是让 AI 代理值得信赖而不仅仅是强大的那一层。敬请关注。