2. 实时风控数据流架构
实时风控系统对延迟极度敏感——从事件发生到做出决策通常要求在 100ms 以内。支撑这一苛刻指标的核心是三层数据流架构:事件驱动架构作为业务模型、消息队列(Kafka)作为数据缓冲与解耦层、流处理引擎(Flink/Spark Streaming)作为计算与切片引擎。三者协同,构成了人群切片与回放验证的物理基础。
2.1 事件驱动架构:风控系统的“神经反射弧”
传统请求-响应模型在风控场景下存在两个致命缺陷:同步阻塞导致决策路径过长,状态丢失导致无法关联历史行为。事件驱动架构(EDA)将每一次用户操作、系统变更、外部信号都封装为不可变事件,通过事件总线异步分发,使风控引擎能够以“订阅-消费”模式实时响应。
| 对比维度 | 请求-响应模型 | 事件驱动架构 |
|---|---|---|
| 耦合度 | 强耦合,调用方必须等待结果 | 松耦合,生产者与消费者完全隔离 |
| 扩展性 | 垂直扩展为主,瓶颈明显 | 水平扩展,可独立扩容消费者 |
| 状态管理 | 无状态或会话级状态 | 事件溯源,完整保留历史 |
| 回放能力 | 不支持,请求即焚 | 天然支持,事件可重放 |
| 典型延迟 | 50-200ms(含业务处理) | 10-50ms(纯事件分发) |
2.2 消息队列(Kafka)在切片中的作用
Kafka 在实时风控中扮演三个关键角色:削峰填谷、事件持久化、多消费者解耦。对于人群切片而言,Kafka 的 分区(Partition) 机制直接决定了切片数据的有序性和并行度。
2.2.1 分区策略与切片对齐
人群切片通常以 用户ID 或 设备指纹 作为分区键。同一用户的所有事件必须路由到同一个分区,才能保证该用户的事件在消费者端严格有序。这是后续滑动窗口切片、状态聚合的前提。
| 分区键 | 适用场景 | 优势 | 风险 |
|---|---|---|---|
| 用户ID | 登录、交易、风控决策 | 用户级有序,切片准确 | 热点用户可能导致分区倾斜 |
| 设备指纹 | 设备关联、团伙检测 | 跨账号关联能力强 | 设备指纹变更频繁 |
| 会话ID | 短时行为序列 | 会话内严格有序 | 跨会话无法关联 |
| 随机键 | 日志采集、非状态计算 | 负载均衡最佳 | 不适用于状态化切片 |
2.2.2 偏移量管理与回放锚点
Kafka 的 偏移量(Offset) 是回放验证的核心锚点。每次切片计算完成后,将当前消费到的偏移量持久化到外部存储(如 Redis 或 MySQL),即可在回放时精确恢复到指定时间点的数据状态。
// 偏移量持久化示例(伪代码)
public class OffsetManager {
public void saveOffset(String groupId, String topic, int partition, long offset) {
String key = "risk:offset:" + groupId + ":" + topic + ":" + partition;
redisTemplate.opsForValue().set(key, String.valueOf(offset));
}
public long loadOffset(String groupId, String topic, int partition) {
String key = "risk:offset:" + groupId + ":" + topic + ":" + partition;
String val = redisTemplate.opsForValue().get(key);
return val == null ? -1L : Long.parseLong(val); // -1 表示从最新开始
}
}
2.3 流处理引擎概览:Flink vs Spark Streaming
流处理引擎是人群切片的“计算大脑”。当前业界主流选择是 Apache Flink 和 Spark Streaming。两者在实时风控场景下的核心差异体现在事件时间语义、状态管理和精确一次语义三个维度。
2.3.1 事件时间 vs 处理时间
人群切片必须使用 事件时间(Event Time),即用户操作发生的真实时间,而非服务器接收到事件的时间。Flink 原生支持事件时间,通过 Watermark 机制处理乱序数据;Spark Streaming 在 Structured Streaming 中才引入事件时间支持,且 Watermark 实现相对粗粒度。
2.3.2 状态后端与切片持久化
切片计算过程中产生的中间状态(如用户最近10笔交易、设备关联IP列表)需要可靠的状态后端。Flink 提供 RocksDB 和 Heap 两种状态后端,支持增量快照;Spark Streaming 则依赖外部存储(如 Redis、HBase)来维护状态。
2.4 本章小结
- 事件驱动架构是实时风控的基石,事件必须包含完整元数据且不可变。
- Kafka 分区策略直接决定切片有序性,用户ID是最常用的分区键。
- 偏移量管理是回放验证的锚点,必须与切片结果原子化保存。
- Flink 在事件时间语义、状态管理和精确一次语义上优于 Spark Streaming,是人群切片的首选引擎。