01
Flink CEP 简介
Flink CEP 是一个基于 Flink Runtime 构建的复杂事件处理库。 它擅长处理跨多个事件的复杂规则匹配场景。 例如,检测用户下单后是否超过半小时没有支付; 检测用户进入直播间后是否浏览商品并加入购物车。
Flink CEP 具有以下优势:
02
业务场景与挑战
随着抖音电商业务逐渐稳定成熟,抖音电商实时数仓团队收到的实时数据规则业务需求逐渐增多,因此我们开始尝试使用 Flink CEP 来支持这些业务场景。
下面列出了两个典型的业务场景,并介绍了 Flink CEP 在这些场景中遇到的一些挑战。
2.1 业务背景
第一个是实时预警场景,这是一个非常典型的业务需求。 它将用户查看数据的方式从“大屏看盘”转变为“根据规则检测结果并主动推送”。 这无疑有助于一些关键业务问题的发现和发展。 洞察力起着至关重要的作用。 具体情况分为以下三种:
二是营销场景落地,由实时数据驱动,按照既定规则和策略挖掘目标人群,根据业务目标进行精准营销。 具体情况分为以下三种:
2.2 业务挑战
首先,规则配置缺乏灵活性。 目前无论是添加规则还是修改规则,研发同学都需要通过实时数仓来通过修改代码来支持,导致研发同学需要频繁对接业务。 在一些极端场景下,比如双十一促销期间,一名研发生往往需要同时响应20多名运营生的创建或修改规则的请求。 业务需求也因人力单点拥堵问题而延迟上线。
其次,规则和计算任务之间存在深度耦合。 当每个规则需要强制绑定一个计算任务时,计算任务的数量会随着规则的创建而逐渐增加。 大量的任务会造成极高的运维成本和巨大的资源浪费,使整个系统最终无法维护。 以前面商户自定义规则检测热门产品的场景为例。 考虑到抖音电商目前庞大的商户群体,创建的规则数量可能会非常巨大,这会导致整个计算任务的数量。 爆炸。
第三,Flink CEP 目前支持的规则语义还不够丰富。 举两个典型案例:
03
解决方案实践
总体来说,我们分为四个阶段来解决上述问题。
第一阶段,我们提炼和抽象了Flink CEP规则的核心信息,设计了一套清晰易懂的规则DSL。 这样可以让商科学生自主配置业务规则,从而解决规则配置灵活性不够的问题。 那么如何让业务配置规则运行起来呢?
第二阶段,我们修改了Flink CEP计算任务,支持动态提交规则或更新规则的能力,从而实现规则和计算任务的完全解耦。 解耦后,不再强制要求每条规则必须对应一个计算任务才能运行。 也就是说,同一个计算任务可以同时接收多个提交的规则,达到收敛整体计算任务数量、提高规则利用率的目的。
前两个阶段要解决规则配置的灵活性以及规则与其他任务强绑定的问题,但仍然没有解决规则本身语义丰富的问题。 因此,第三阶段我们主要针对具体业务场景进行规则诉求、规则语义的升级和扩展。
经过前三阶段的升级优化,上述业务痛点已基本解决,但规则引擎在易用性和外围能力方面仍存在不足。 例如,我们无法直观地查看当前系统运行的规则内容和注册事件数据; 采用什么策略来分配业务提交的规则和计算任务; 用户仍然需要订阅规则引擎的输出数据进行格式转换和写入Target存储等操作。
因此,在第四阶段,我们整合了之前的解决方案,不断丰富周边的能力生态,打造一站式实时规则平台。 支持用户在平台上进行独立操作,包括事件注册、预览、规则配置、规则调试、规则发布等,进一步提高工作效率。
为了实现自主的业务配置规则,规则的语法必须清晰易懂。 我们设计的规则DSL将JSON和基本SQL语法结合为一体,利用JSON的高可读性来描述规则的元数据、规则匹配属性等信息,利用SQL强大的表达能力来描述CEP匹配匹配结果的条件和处理逻辑。 。
这里我们发现了一个新问题,如何通过SQL表达事件是否满足匹配条件? SQL可以查询哪些表? 我们通过一个具体案例来回答这个问题。
假设要检测用户下单后是否发生支付行为,那么规则编译生成的NFA可能如下图所示。 当规则运行时,我们将当前传入的事件以及当前规则的中间匹配结果以数据表的形式注册到上下文中。 当前传入的事件对应的表名默认为events,规则中匹配结果对应的表名与其PatternName一致。
这种情况下,每个SQL中可以查询三个表,即events表,代表当前传入的事件; create_order表,代表当前匹配的订单事件; pay_order 表,代表匹配的付款。 事件。
配置SQL时,您可以查询任何已注册到上下文的数据表。 当SQL查询结果不为空时,表示当前匹配条件通过。 状态机通过Take端流向下一个状态,并将事件保存到相应的表中。 否则,它将转到忽略端并丢弃该事件。
我们看一下本例对应的规则配置条件的完整配置。 整体是一个数组的形式。 数组中的每个元素代表一种模式。 第二个模式与前一个模式之间的连接类型是 FOLLOWED_BY。 第一个模式的匹配条件是从流量中检测用户下单事件,第二个模式的匹配条件是从流入中检测用户支付事件。
注意,这个支付事件的顺序就是我们上一步缓存的订单事件对应的顺序。 经过上述改造后,凡是有一定SQL基础知识的业务人员都可以理解并配置规则。
前面我们提到,目前的 Flink CEP 计算任务不支持动态提交规则。 主要原因是Flink CEP规则计算逻辑在编译阶段就确定了,已经通过NFACompiler编译完成。 在运行时,计算任务只能执行先前编译的规则。 那么我们如何改造它呢?
为了实现规则的动态发现,我们引入了规则流,用户提交或者修改的规则都可以发送到这个流中。 为了实现规则的动态注入,我们将规则流设计为广播流。 当发现新提交的规则时,会向所有子任务分发广播。
为了实现规则的在线加载和执行,我们在上述规则DSL的基础上开发了一套基于规则的解析器。 SubTask接收到分布式规则后,可以分析并生成在线运行规则所需的组件。 比如NFA、规则匹配条件SQL对应的执行计划、匹配结果处理函数等。然后将其保存到Flink State中,以持续检测和处理后续事件。
解释一下为什么使用Broadcast Stream来实现规则的动态注入。 由于Flink CEP是有状态的计算,规则的更新/删除往往需要Flink State的操作和处理。 例如:删除规则时,与当前规则关联的事件缓存等状态信息也需要删除。 相比于通过其他方式感知规则变化,比如启动异步线程定期扫描规则,使用 Broadcast Stream 的优势在于,当检测到规则变化时,可以更加方便、安全地操作 Flink State。
上述方案解决了计算任务动态提交规则的需求,但是当计算任务运行多个规则时,带来了新的问题。
问题1:规则的事件分组逻辑可能不同。 (例如,规则A在进行NFA匹配计算之前需要根据“用户的IP地址”将事件流路由到同一个Task。规则B需要根据“用户的设备ID”将事件流路由到)。 那么这两个规则在同一个计算任务上运行时如何兼容呢?
为了解决这个问题,我们添加了KeyGenOperator操作符。 当检测到新的事件时,首先根据每个规则配置生成对应的分组键,然后根据分组键分发下游任务。 这样就实现了对多种规则的不同事件分组逻辑的兼容。 。
问题2:由于同一个计算任务运行多个规则,可能会造成规则计算冗余。 例如,规则A关注用户下单、支付等支付相关事件,而规则B关注用户商品浏览、评论等流量相关事件。 如果同一个计算任务同时运行这两种规则,那么该任务必须同时消费两种类型的事件。 也就是说,规则A并不关注流量类型的事件抖音浏览自助平台,但由于整个任务都订阅了此类事件,因此规则A也必须处理此类事件。
为了解决上述问题,我们在KeyGenOperator算子中添加了“事件过滤”组件,实现对同一输入事件在不同规则下的个性化事件过滤。 也就是说,对于新传入的事件,只有当规则关注到该事件时,才会生成相应的分组键并进行后续的计算。
值得一提的是,在商户定制预警的业务场景中,由于事件过滤的效果比较好(即每个商户定义的规则只关注与当前商户产品相关的事件),那么在我们测试单个任务(600Core、800并发条件下)可以支持超过百万条简单商户规则。
当事件A发生后一段时间内事件B没有发生时,对应的伪代码可以是如上的形式。 目前的 Flink CEP 不支持这个语义,因为可能会导致没有事件触发这个规则并最终完成匹配。
为了解决这个问题,我们在规则生成的 NFA 中引入了 Pending 状态。 当流入事件满足创建订单条件时,状态将迁移至 Pending 状态并等待超时。 当Flink CEP任务的watermark前进时,会触发Pending状态的NFC进行计算,判断是否超时。 如果超时,NFA将被触发并迁移到下一个Final状态。 如果在此之前有订单支付事件流入系统,则会转入Stop状态。
这样抖音浏览自助平台,我们就实现了对事件A发生后一段时间内发生的事件B的语义的支持。
为了进一步提高规则引擎的适用性,我们整合了之前的解决方案,扩展了规则引擎的外围能力,开发了一站式规则平台。 用户可以在平台上自助完成事件注册、预览、规则配置、调试、发布的全流程。
整个平台架构分为四层,分别是:
事件层,如查看事件、下单事件、物流事件、客服事件等。
计算层负责动态接收用户提交的CEP规则,解析规则,检测后续流入事件。 计算层的核心是规则计算模块,它是具体的Flink CEP计算任务。 同时,计算层还有规则调度模块和规则解析模块。 规则调度模块负责将新提交的规则分发到具体的Flink CEP计算任务。 调度策略可以选择相同事件源优先级或负载均衡优先级。
触达层负责计算层规则匹配结果的数据应用,主要包括延迟策略管理、维度字段扩展、推送目标管理等。
平台层负责与用户交互以及任务运维。
经营业绩:
技术成果:
04
未来展望
未来,我们计划继续从以下三个方面进行规则引擎的建设。
过去的选择
发表评论