4. CEP 核心概念:事件、流、模式、规则、匹配策略、时间语义
做反欺诈这么多年,我越来越觉得 CEP 就是规则引擎的灵魂。你想想看,用户在一分钟内连续登录三次失败,紧接着又发起转账——这种“序列”写普通的 if-else 累死人,但在 CEP 里几句话就搞定了。
这一节我把 CEP 的核心概念拆开揉碎了讲。你听我说完,再去写代码心里就有谱了。
4.1 事件与流——Cep 的“细胞”和“血液”
事件就是一条数据。在反欺诈场景里,事件可以是一次登录、一笔支付、一个改密操作。我对事件的规定很简单:至少包含一个时间戳和一个唯一标识。比如:
// 伪代码示意
case class LoginEvent(userId: String, ip: String, timestamp: Long)
case class PaymentEvent(userId: String, amount: Double, timestamp: Long)
流就是事件的集合,按时间排成队。Flink 处理的是无界流,也就是数据永不停。我个人习惯把流分成两种:
- 原始事件流:从 Kafka 直接接入,脏数据最多,需要过滤。
- 预处理流:经过清洗、字段对齐后的干净流,CEP 直接消费它。
我记得有一次生产环境里,事件的时间戳是字符串,没解析就直接丢进 CEP,结果模式永远匹配不上。嗯,这种坑踩过一次就够了。
4.2 模式——你要抓的“行为序列”长什么样
模式就是一系列相关事件的“骨架”。在 Flink CEP 里,我们用 Pattern<Event, ?> 来定义。举个例子:
Pattern<LoginEvent, ?> pattern = Pattern
.<LoginEvent>begin("first")
.where(new SimpleCondition<LoginEvent>() {
@Override
public boolean filter(LoginEvent event) {
return event.result.equals("FAIL");
}
})
.next("second") // 严格连续
.where(...)
.within(Time.minutes(5));
这里 begin 是第一个事件节点,next 表示“紧接着下一个”。你可能会问:为什么不用 followedBy?区别就在匹配策略里。
4.3 匹配策略——邻居之间的距离
这是新手最容易晕的地方。Flink CEP 提供了三种连续关系:
| 策略 | 关键字 | 含义 | 我在项目中常见的用法 |
|---|---|---|---|
| 严格连续 | next |
两个事件必须紧挨着,中间不能有任何其他事件 | 连续三次登录失败,中间不能有成功登录 |
| 宽松连续 | followedBy |
允许中间有其他事件,但顺序要正确 | 登录失败 -> 几秒后转账,中间可以有点击广告行为 |
| 非确定性宽松连续 | followedByAny |
允许跳过匹配过的事件,用于重复利用事件 | 同一设备多次触发风控规则,需要每次都计一次 |
你别看表格看着挺整齐,实际选错策略会让你要么漏报要么误报。我曾经因为用 next 替代 followedBy,导致正常用户的一次支付被死等前一个事件,结果超时没触发。调了两天才发现。
4.4 规则——模式+阈值+动作
模式只是“骨架”,加上阈值和动作才成为规则。比如:
- 模式:登录失败 -> 登录失败 -> 登录失败
- 阈值:5 分钟内发生
- 动作:标记用户为高风险,发送告警到 Kafka
在 Flink CEP 中,规则通常封装在一个 PatternStream 里,然后通过 .process() 输出匹配结果。我的团队把规则存到外部配置中心(如 Nacos),动态更新,不用重启作业。
4.5 时间语义——事件时间才是真爱
这是 CEP 的核心难点。Flink 支持两种时间:
- 处理时间:Flink 机器当前的时间。简单,但结果不可复现。
- 事件时间:事件真实发生的时间。需要 Watermark 配合,但结果可回溯。
反欺诈场景下,你必须用事件时间。为什么?因为攻击者可能故意延迟发送事件,干扰你的判断。你用处理时间,就会把不同时段的行为错误的拼接在一起。
举个例子:正常用户的登录失败发生在上午 10:00,风控系统在 10:02 收到;而攻击者把一条转账事件故意延迟到 10:05 才发,如果按处理时间,这两个事件就“碰”在了一起,本该不触发规则却触发了。这就是我踩过的坑。
assignTimestampsAndWatermarks,Watermark 间隔不要太大(一般 1~5 秒),否则延迟事件太多会导致规则失效。
下面这张图总结了 CEP 的核心流程,你看一遍就能把前面几个概念串起来:
你看,事件流和模式、匹配策略共同输入规则,规则再结合时间语义的约束,最终产生告警。这里面任何一环出问题,结果都不对。