1. CEP 基础概念:事件、事件流、事件模式、复杂事件处理定义

各位同学好,我是这门课的主讲。今天咱们聊聊 CEP 最基础的东西——事件、事件流、事件模式,以及到底什么是复杂事件处理。

说实话,我刚开始接触推荐系统时,觉得“事件”不就是用户点了个按钮嘛,有啥好讲的?后来在美团做实时推荐,每天处理几十亿条用户行为日志,才发现——事件的定义,直接决定了你能从数据里挖出什么价值。

1.1 什么是事件?

事件,说白了就是“在某个时间点,发生了某件事”。它有三个核心要素:

  • 时间戳:什么时候发生的?
  • 主体:谁干的?
  • 动作/属性:干了什么?附带什么信息?

举个例子,用户小明在 2024-01-15 10:30:00 点击了商品 A,这就是一个事件:

{
  "event_type": "click",
  "user_id": "xiaoming",
  "item_id": "A",
  "timestamp": 1705293000000,
  "page": "homepage"
}

我在项目中见过不少团队,把事件字段定义得特别随意。比如“page”字段有时写“home”,有时写“首页”,有时写“1”。这种不一致,到了 CEP 阶段就是灾难。所以我建议,事件结构一定要在项目初期就定好规范。

我的经验:事件定义时,尽量把“时间戳”统一成毫秒级 Unix 时间戳,别用字符串。字符串解析在流式处理中会吃掉大量性能。

1.2 事件流:事件在时间线上的“河流”

单个事件没什么意思。真正有价值的是事件流——事件按照时间顺序,源源不断地到达。

你可以把事件流想象成一条河。河水(事件)不停地流,你站在岸边(处理系统),观察河面上漂过的每一片叶子(事件)。

事件流有几个关键特征:

  • 无限性:理论上事件是无穷无尽的,你没法等所有事件到齐再处理
  • 时序性:事件到达的顺序很重要,先点广告再下单,和先下单再点广告,含义完全不同
  • 无序性:实际系统中,事件可能乱序到达。比如用户手机离线,几条事件一起上传

我记得在滴滴做推荐时,遇到过一个问题:用户先点击了“快车”按钮,然后过了 3 秒又点击了“拼车”。按理说应该推荐拼车相关的商品,但事件流里两条记录的时间戳只差了 1 毫秒——因为客户端批量上报了。这就是典型的乱序问题。

1.3 事件模式:你要找的“故事”

事件模式,就是你感兴趣的事件序列模板。它描述了“什么样的事件组合,在什么样的时间关系下,构成了一个有意义的故事”。

举个推荐场景的例子:

你想找出“对商品感兴趣但犹豫不决的用户”,这个模式可能是:

  1. 用户搜索了关键词“运动鞋”
  2. 在 5 分钟内,查看了至少 3 款运动鞋的商品详情页
  3. 但没有加入购物车

用 CEP 的术语,这就是一个事件模式。模式里通常包含:

模式要素 说明 推荐场景举例
事件类型 你关心哪些事件 search, view, add_to_cart
时序关系 事件发生的先后顺序 先搜索,再浏览
时间窗口 事件必须在多长时间内发生 5 分钟内
数量约束 某类事件至少/至多出现几次 至少查看 3 次
属性条件 事件属性必须满足的条件 商品类别 = "运动鞋"
核心观点:事件模式就是你对用户行为的“假设”。你假设某种行为序列意味着“感兴趣”,然后让 CEP 引擎去实时验证这个假设。

1.4 复杂事件处理(CEP)的定义

好了,前面三个概念都铺垫完了。现在说说 CEP 到底是什么。

复杂事件处理(Complex Event Processing, CEP),是一种从简单事件流中,实时检测出有意义的复杂事件模式的技术。

说白了,就是:

  • 输入:一堆简单事件(点击、浏览、购买……)
  • 处理:用你定义的模式去匹配
  • 输出:一个“复杂事件”(比如“这个用户可能要流失了”)

CEP 和普通的流处理(比如 Flink 的简单过滤)有什么区别?我画了张图:

CEP vs 普通流处理 普通流处理 过滤、聚合、转换 单条事件独立处理 无状态或简单状态 例:统计每分钟点击数 复杂事件处理 (CEP) 模式匹配、序列检测 多条事件关联分析 维护跨事件的状态 例:检测“浏览→加购→未支付” CEP 的核心能力:在时间维度上,把多个孤立事件“串”成一个有业务含义的故事 推荐场景中,用户的一次完整决策往往由 5~20 个事件组成,CEP 就是用来捕捉这个“决策链”的 CEP 处理流程示例 事件流输入 模式匹配 状态管理 复杂事件输出

CEP 和普通流处理最大的区别在于:CEP 关注的是事件之间的关系,而不是单个事件本身。普通流处理看到的是“小明点击了商品 A”,CEP 看到的是“小明先搜索了运动鞋,然后浏览了 3 款,最后点击了商品 A——这是一个典型的‘比价行为’模式”。

避坑提醒:我曾经犯过一个错误——把 CEP 当成万能工具,什么逻辑都往模式里塞。结果模式越来越复杂,性能越来越差。后来我总结了一条原则:CEP 只做“跨事件的时序逻辑”,单事件的过滤和计算,交给上游的普通流处理去做。

1.5 为什么推荐系统需要 CEP?

你可能会问:推荐系统不是有协同过滤、深度学习模型吗?CEP 能干啥?

嗯,这个问题我当年也问过。后来在字节做推荐时,发现一个痛点:模型只能看到“当前状态”,看不到“用户是怎么走到这一步的”。

举个例子:

  • 用户 A:打开 App → 搜索“火锅” → 浏览 5 家店 → 点击第 3 家 → 下单
  • 用户 B:打开 App → 首页推荐流 → 直接点击第 3 家 → 下单

两个用户都下单了,但行为路径完全不同。模型只看“当前特征”,很难区分这两种场景。而 CEP 可以实时检测出“用户 A 是主动搜索型,用户 B 是被动推荐型”,然后给不同的推荐策略。

CEP 在推荐系统中的典型应用场景:

场景 CEP 模式 推荐动作
实时意图识别 搜索 → 浏览同类商品 ≥ 3 次 推送该类商品优惠券
流失预警 30 分钟内无任何交互 发送 push 召回
比价行为检测 查看商品 A → 查看商品 B(同类)→ 返回商品 A 推送商品 A 的限时折扣
新用户冷启动 注册 → 首次浏览 → 首次点击 记录偏好,调整初始推荐列表
一个小建议:刚开始用 CEP 时,别想着一步到位。先挑 1~2 个最核心的模式跑通,比如“加购未支付”这种高价值模式。等团队熟悉了 CEP 的思维方式,再逐步扩展。

好了,这一章的内容就到这里。CEP 的基础概念其实不复杂,但它是后面所有内容的地基。事件、事件流、事件模式、复杂事件处理——这四个概念,你可以在后面的每一章里看到它们的身影。