3. 流式决策架构概览:事件驱动架构、实时特征计算、决策引擎、反馈闭环
信用额度定价的流式决策架构,本质上是将传统的“请求-响应”批处理模式,升级为“事件-处理-反馈”的实时闭环。该架构围绕四个核心组件构建:事件驱动架构作为数据管道、实时特征计算作为特征工厂、决策引擎作为定价大脑、反馈闭环作为持续学习回路。以下从架构分层与数据流两个维度展开。
3.1 架构核心组件与职责
流式决策架构通常分为四层,每层承担明确的职责,并通过异步消息或流处理框架连接。
| 架构层 | 核心组件 | 主要职责 | 典型技术选型 |
|---|---|---|---|
| 事件接入层 | 事件总线 / 消息队列 | 接收用户行为、交易、征信变更等实时事件,保证至少一次投递 | Apache Kafka, AWS Kinesis, Pulsar |
| 实时特征层 | 特征服务 + 流计算引擎 | 对事件流进行窗口聚合、特征衍生、特征存储与在线获取 | Spark Structured Streaming, Flink, Redis, Feature Store |
| 决策执行层 | 决策引擎 / 规则引擎 | 加载定价模型、执行规则、计算信用额度与利率 | Drools, 自研决策引擎, ONNX Runtime |
| 反馈闭环层 | 结果回写 + 离线训练管道 | 收集决策结果、用户后续表现,驱动模型迭代与特征漂移检测 | Delta Lake, Hudi, MLflow, 离线训练 Pipeline |
架构要点: 实时特征层是连接事件与决策的“桥梁”。特征服务必须同时支持在线低延迟获取(毫秒级)和离线批量回溯(T+1 训练),这是流式决策区别于传统实时规则引擎的关键。
3.2 事件驱动架构:流式决策的“神经系统”
事件驱动架构(EDA)是流式决策的基础。所有业务动作——用户申请、还款、消费、征信查询——都被封装为不可变事件,发布到事件总线。下游消费者(特征计算、决策引擎、审计系统)通过订阅事件流实现解耦与异步处理。
- 事件类型:申请事件(application_event)、交易事件(transaction_event)、状态变更事件(status_change_event)、外部数据事件(external_data_event)。
- 事件格式:推荐使用 Avro 或 Protobuf 进行序列化,保证 schema 兼容性与演化能力。
- 分区策略:按用户 ID 或申请 ID 分区,确保同一用户的事件顺序消费,避免并发定价冲突。
实践建议: 在 Kafka 中为信用额度定价场景设置独立的 topic(如
credit_pricing_event),并配置合理的日志保留时间(建议 7 天以上),以支持事件回溯与故障恢复。
3.3 实时特征计算:从事件到特征的“炼金术”
原始事件无法直接用于模型决策,必须经过特征计算转化为结构化特征。实时特征计算的核心挑战在于:在毫秒级延迟内,完成窗口聚合、跨事件关联、外部特征拼接。
Spark Structured Streaming 在该层扮演关键角色。以下是一个典型的实时特征计算流程:
// 伪代码:Spark Structured Streaming 实时特征计算
val eventStream = spark
.readStream
.format("kafka")
.option("subscribe", "credit_pricing_event")
.load()
// 1. 解析事件,提取用户ID、事件类型、时间戳
val parsedStream = eventStream
.selectExpr("CAST(value AS STRING) as json")
.select(from_json($"json", eventSchema).as("event"))
.select("event.user_id", "event.event_type", "event.event_time")
// 2. 滑动窗口聚合:过去30天内的申请次数、总借款金额
val windowedFeatures = parsedStream
.withWatermark("event_time", "10 minutes")
.groupBy(window($"event_time", "30 days", "1 day"), $"user_id")
.agg(
count("*").alias("app_count_30d"),
sum("loan_amount").alias("total_loan_30d")
)
// 3. 与离线特征拼接(通过特征服务API)
val enrichedStream = windowedFeatures
.map(row => {
val onlineFeatures = FeatureService.getOnlineFeatures(row.user_id)
// 合并在线与离线特征
Row.fromSeq(row.toSeq ++ onlineFeatures.toSeq)
})
避坑提示: 实时特征计算必须处理迟到事件与乱序事件。Spark 的 watermark 机制可以容忍一定延迟,但窗口大小与 watermark 间隔需要根据业务容忍度精细调优。对于信用定价场景,建议 watermark 设置为窗口大小的 1/3 到 1/2。
3.4 决策引擎:定价模型的“执行器”
决策引擎接收实时特征向量,执行定价模型,输出信用额度与利率。该层需要同时支持规则驱动(如监管限制、风险底线)和模型驱动(如机器学习模型、评分卡)。
典型的决策流程包含三个阶段:
- 规则前置过滤:检查用户是否在黑名单、是否满足年龄/收入硬性门槛,快速拒绝无效请求。
- 模型评分:加载预训练的定价模型(如 XGBoost、神经网络),输入实时特征,输出初始额度与利率。
- 后处理调整:根据业务策略(如新客优惠、渠道差异化)对模型输出进行微调,生成最终定价。
性能目标: 决策引擎的 P99 延迟应控制在 50ms 以内。超过该阈值,用户侧感知延迟将显著增加,影响转化率。建议将模型推理部署为独立微服务,并通过 gRPC 或 RESTful API 与决策引擎通信。
3.5 反馈闭环:让系统“越用越聪明”
流式决策架构区别于传统静态规则系统的核心,在于反馈闭环。每次决策结果、用户后续的还款/逾期行为、额度使用率等数据,都会被回写至离线存储,用于模型训练与特征评估。
反馈闭环的典型工作流:
- 在线回写:决策引擎将定价结果(额度、利率、决策原因码)写入 Kafka 回写 topic,由 Flink/Spark 作业落地到 Delta Lake 或 Hudi。
- 离线训练:每日凌晨,离线训练管道读取回写数据与用户表现标签,重新训练定价模型。
- 特征漂移检测:对比在线特征分布与离线训练集分布,若检测到显著漂移,触发告警并自动回滚至上一版本模型。
- 模型热更新:新模型通过特征服务配置中心下发,决策引擎在下一轮决策时自动加载新版本,无需重启服务。
关键指标: 反馈闭环的健康度可通过 特征新鲜度(特征从事件产生到可用于决策的延迟)和 模型迭代周期(从数据回写到新模型上线的时间)来衡量。理想状态下,特征新鲜度应 < 5 秒,模型迭代周期应 < 24 小时。
3.6 流式决策架构总览图
下图展示了信用额度定价流式决策的完整数据流与组件关系:
3.7 架构关键设计原则
基于上述组件与数据流,流式决策架构的设计应遵循以下原则:
| 原则 | 说明 | 实现方式 |
|---|---|---|
| 解耦与异步 | 各层通过事件总线通信,避免同步阻塞 | Kafka 作为核心消息中间件,生产者/消费者模式 |
| 状态与无状态分离 | 特征计算维护状态(窗口聚合),决策引擎保持无状态 | Spark 状态后端(RocksDB)管理聚合状态;决策引擎无状态化部署 |
| 可观测性 | 全链路追踪事件处理延迟与决策结果 | OpenTelemetry 埋点 + 自定义 Metrics(特征新鲜度、决策延迟、模型版本) |
| 容错与 Exactly-Once | 保证事件不丢失、不重复处理 | Kafka 幂等生产者 + Spark 端到端 Exactly-Once 语义 + 事务性写入 Delta Lake |