Arch Day 113
Arch Day 113: 系统设计面试(4) — 设计实时风控系统
Arch Day 113: 系统设计面试(4) — 设计实时风控系统
2026-03-29
第四阶段 - 高阶融合系统设计实时风控特征平台决策引擎规则引擎ML模型案件系统
日期: 2026-03-29 (Day 113) 阶段: 第四阶段 - 高阶融合 标签: #系统设计 #实时风控 #特征平台 #决策引擎 #规则引擎 #ML模型 #案件系统
面试模拟 — 45分钟
面试场景
面试官: "请设计一个实时风控系统,用于电商/支付场景。要求在每笔交易发生时实时判断风险等级,延迟要求<50ms。每天交易量约500万笔。"
第一步:需求澄清(5分钟)
我的提问
功能需求确认:
Q1: 风控介入的时机?
A: 交易发起时同步判定(支付前),也有异步的事后分析。
Q2: 风控结果有哪些?
A: 通过/拒绝/人工审核/二次验证(短信/人脸)。
Q3: 需要覆盖哪些风险类型?
A: 盗刷、欺诈、洗钱、薅羊毛、机器人批量操作。
Q4: 规则谁来配置?
A: 风控运营人员,需要可视化规则配置,不需要开发介入。
Q5: 误报率要求?
A: <1%(每100笔正常交易最多1笔被误拒)。
非功能需求确认:
Q6: 延迟要求?
A: P99<50ms(同步判定)。
Q7: 日均交易量?
A: 500万笔/天,峰值1500万笔(大促)。
Q8: 规则数量?
A: 当前200+条规则,未来可能到1000+。
Q9: 特征计算?
A: 需要实时计算用户历史行为特征(最近1小时/24小时/7天)。
Q10: 模型更新频率?
A: 规则实时生效,ML模型每周更新。
需求总结
核心挑战:
├── 极低延迟: <50ms(含特征计算+规则执行+模型推理)
├── 高吞吐: 峰值~175 TPS(1500万/天)
├── 实时特征: 需要"最近1小时该用户交易次数"这类滑动窗口特征
├── 规则+ML混合: 规则处理已知模式,ML检测未知模式
├── 低误报: <1%误报率(否则影响用户体验和GMV)
├── 快速迭代: 新规则分钟级生效,不需要发版
└── 案件管理: 拒绝/审核的交易需要案件系统跟进
第二步:高层设计(10分钟)
2.1 架构总览
实时风控系统架构:
┌──────────────────────────────────────────────────────────────┐
│ │
│ 交易系统 │
│ │ │
│ │ 同步调用(<50ms) │
│ ▼ │
│ ┌──────────────────────────────────────────────────────┐ │
│ │ Risk Gateway (风控网关) │ │
│ │ ├── 请求路由(按业务类型选择策略) │ │
│ │ ├── 熔断降级(风控不可用时的兜底策略) │ │
│ │ └── 结果缓存(同一用户短时间内重复查询) │ │
│ └────────────────────┬─────────────────────────────────┘ │
│ │ │
│ ┌────────────────────┴─────────────────────────────────┐ │
│ │ Feature Engine (特征引擎) │ │
│ │ ├── 在线特征: Redis获取(<5ms) │ │
│ │ │ 用户近1h交易次数/金额/设备指纹 │ │
│ │ ├── 离线特征: 预计算好存Redis(<5ms) │ │
│ │ │ 用户历史信用分/注册天数/常用地址 │ │
│ │ └── 实时特征: Flink流计算(<100ms延迟) │ │
│ │ 滑动窗口聚合/序列模式 │ │
│ └────────────────────┬─────────────────────────────────┘ │
│ │ │
│ ┌────────────────────┴─────────────────────────────────┐ │
│ │ Decision Engine (决策引擎) │ │
│ │ │ │
│ │ ┌──────────┐ ┌──────────┐ ┌──────────────┐ │ │
│ │ │ 规则引擎 │───→│ ML模型 │───→│ 决策融合 │ │ │
│ │ │ (Rules) │ │ (Model) │ │ (Fusion) │ │ │
│ │ │ │ │ │ │ │ │ │
│ │ │ 200+条 │ │ XGBoost │ │ 规则优先 │ │ │
│ │ │ 白/黑名单│ │ 或 │ │ ML补充 │ │ │
│ │ │ 频率规则 │ │ 深度学习 │ │ 加权融合 │ │ │
│ │ │ 金额规则 │ │ │ │ │ │ │
│ │ └──────────┘ └──────────┘ └──────┬───────┘ │ │
│ │ │ │ │
│ │ 风控结论 │ │
│ │ PASS/REJECT/REVIEW │ │
│ │ /CHALLENGE │ │
│ └──────────────────────────────────────────────────────┘ │
│ │ │
│ │ 异步 │
│ ▼ │
│ ┌──────────────────────────────────────────────────────┐ │
│ │ Case Management (案件系统) │ │
│ │ ├── REVIEW案件: 人工审核队列 │ │
│ │ ├── REJECT案件: 自动记录+申诉通道 │ │
│ │ ├── 标注反馈: 审核结果→模型训练数据 │ │
│ │ └── 报表统计: 风控效果分析 │ │
│ └──────────────────────────────────────────────────────┘ │
│ │
└──────────────────────────────────────────────────────────────┘
2.2 核心数据流
一笔交易的风控判定流程(目标<50ms):
T+0ms: 交易请求到达风控网关
T+2ms: 解析请求,提取关键字段(用户/金额/设备/IP)
T+3ms: 并行发起特征获取:
├── Redis GET 在线特征(用户画像/历史统计) → T+8ms返回
├── Redis GET 离线特征(信用分/注册天数) → T+7ms返回
└── Redis GET 实时特征(近1h交易次数/金额) → T+8ms返回
T+10ms: 特征组装完成(等待最慢的那个)
T+12ms: 规则引擎执行:
├── 黑名单匹配 → 命中则直接REJECT
├── 白名单匹配 → 命中则直接PASS
├── 频率规则 → 1h内>10笔 → 高风险
├── 金额规则 → 超出历史均值5倍 → 高风险
└── 设备规则 → 新设备+大额 → 高风险
T+25ms: ML模型推理:
├── 特征向量→XGBoost模型→风险分(0-1000)
├── 推理延迟: ~5ms(XGBoost) 或 ~10ms(DNN)
└── 返回: 风险分 + 可解释性Top3因子
T+35ms: 决策融合:
├── 规则命中"黑名单" → 直接REJECT(不看模型)
├── 规则命中"白名单" → 直接PASS(不看模型)
├── 规则无明确结论 → 看模型分:
│ ├── 模型分>800 → REJECT
│ ├── 模型分>600 → REVIEW(人工审核)
│ ├── 模型分>400 → CHALLENGE(二次验证)
│ └── 模型分≤400 → PASS
└── 规则和模型冲突 → 取较严格的结论
T+40ms: 返回风控结论
T+42ms: 异步: 记录风控日志 + 触发案件(如有)
总耗时: 42ms < 50ms ✓
第三步:核心组件设计(15分钟)
3.1 特征平台 ★ 核心
风控特征平台设计:
┌──────────────────────────────────────────────────────────┐
│ Feature Platform for Risk │
├──────────────────────────────────────────────────────────┤
│ │
│ ┌─── 离线特征(T+1) ───────────────────────────────┐ │
│ │ 计算引擎: Spark Batch (每日凌晨) │ │
│ │ 存储: Redis (TTL=24h) + Hive(历史) │ │
│ │ │ │
│ │ 特征示例: │ │
│ │ ├── user:credit_score → 720 │ │
│ │ ├── user:register_days → 365 │ │
│ │ ├── user:history_order_count → 156 │ │
│ │ ├── user:avg_order_amount → 28800 (分) │ │
│ │ ├── user:common_address_hash → "abc123" │ │
│ │ ├── user:device_count_30d → 2 │ │
│ │ └── user:refund_rate_90d → 0.03 │ │
│ │ │ │
│ │ 延迟: Redis GET ~3ms │ │
│ └───────────────────────────────────────────────────┘ │
│ │
│ ┌─── 近线特征(分钟级) ────────────────────────────┐ │
│ │ 计算引擎: Flink Streaming │ │
│ │ 数据源: Kafka (交易事件流) │ │
│ │ 存储: Redis (TTL=按窗口大小) │ │
│ │ │ │
│ │ 特征示例(滑动窗口): │ │
│ │ ├── user:txn_count_1h → 3 (最近1小时交易数) │ │
│ │ ├── user:txn_amount_1h → 56000(最近1小时交易额) │ │
│ │ ├── user:txn_count_24h → 8 (最近24小时交易数) │ │
│ │ ├── user:distinct_ip_1h → 1 (最近1小时IP数) │ │
│ │ ├── user:distinct_device_24h → 1 (24h设备数) │ │
│ │ └── user:failed_pay_count_1h → 0 (1h支付失败数) │ │
│ │ │ │
│ │ Flink实现(滑动窗口聚合): │ │
│ │ ├── 1分钟tumbling window: 先按分钟聚合 │ │
│ │ ├── 1小时sliding window: 累加最近60个1分钟桶 │ │
│ │ ├── 结果写入Redis: SETEX key 3600 value │ │
│ │ └── 延迟: 事件到特征可用 ~30秒 │ │
│ │ │ │
│ │ 延迟: Redis GET ~3ms │ │
│ └───────────────────────────────────────────────────┘ │
│ │
│ ┌─── 在线特征(实时) ──────────────────────────────┐ │
│ │ 计算引擎: 风控服务内实时计算 │ │
│ │ 数据源: 当前请求 │ │
│ │ │ │
│ │ 特征示例: │ │
│ │ ├── txn:amount → 99900 (当前交易金额) │ │
│ │ ├── txn:amount_vs_avg → 3.47 (当前/历史均值) │ │
│ │ ├── txn:is_new_device → 1 (是否新设备) │ │
│ │ ├── txn:is_new_ip → 0 (是否新IP) │ │
│ │ ├── txn:hour_of_day → 3 (凌晨3点) │ │
│ │ ├── txn:ip_risk_score → 20 (IP风险评分) │ │
│ │ └── txn:device_fingerprint → "xyz789" │ │
│ │ │ │
│ │ 延迟: ~1ms (内存计算) │ │
│ └───────────────────────────────────────────────────┘ │
│ │
│ 特征总数: ~100个 │
│ 特征获取总延迟: ~5-8ms (并行获取) │
└──────────────────────────────────────────────────────────┘
3.2 规则引擎
规则引擎设计:
┌──────────────────────────────────────────────────────────┐
│ Rule Engine │
├──────────────────────────────────────────────────────────┤
│ │
│ 规则类型: │
│ │
│ 1. 名单规则 (最高优先级, <1ms) │
│ ├── 黑名单: 用户/设备/IP/卡号 → 直接REJECT │
│ ├── 白名单: VIP客户/内部测试 → 直接PASS │
│ └── 灰名单: 历史可疑 → 进入加强验证 │
│ 存储: Redis Set (SISMEMBER O(1)) │
│ │
│ 2. 频率规则 (~2ms) │
│ ├── 同一用户1小时内交易≥10次 → REVIEW │
│ ├── 同一设备1天内交易≥20次 → REJECT │
│ ├── 同一IP 10分钟内交易≥50次 → REJECT(可能是攻击) │
│ └── 同一银行卡1小时内尝试≥5次 → CHALLENGE │
│ 实现: Redis INCR + EXPIRE (滑动窗口) │
│ │
│ 3. 金额规则 (~1ms) │
│ ├── 单笔>历史均值×5 → REVIEW │
│ ├── 单笔>50000 → 加强验证 │
│ ├── 日累计>200000 → REVIEW │
│ └── 首笔交易>10000(新用户) → CHALLENGE │
│ 实现: 内存计算(从特征获取历史数据) │
│ │
│ 4. 场景规则 (~2ms) │
│ ├── 凌晨2-5点 + 大额 → REVIEW │
│ ├── 新设备 + 新IP + 大额 → REJECT │
│ ├── 异地交易(与常用地址不同) + 大额 → CHALLENGE │
│ └── 短时间更换设备>3次 → REVIEW │
│ 实现: 条件组合判断 │
│ │
│ 规则执行策略: │
│ ├── 串行执行: 按优先级从高到低 │
│ │ 名单→频率→金额→场景 │
│ ├── 短路: 命中黑名单直接REJECT(不执行后续规则) │
│ ├── 累加: 多条规则命中→风险分累加→最终判定 │
│ └── 调试模式: 新规则先Shadow(只记录不执行) │
│ │
│ 规则管理: │
│ ├── 可视化配置界面(风控运营人员自助) │
│ ├── 规则版本管理(可回滚) │
│ ├── 灰度发布(先对1%流量生效) │
│ ├── 实时生效(修改→发布→<1分钟生效) │
│ │ 实现: 配置中心(Nacos/Apollo)推送→服务热加载 │
│ └── 效果统计(每条规则的命中率/误报率) │
│ │
└──────────────────────────────────────────────────────────┘
3.3 ML模型Serving
风控ML模型架构:
┌──────────────────────────────────────────────────────────┐
│ ML Model Serving │
├──────────────────────────────────────────────────────────┤
│ │
│ 模型类型: │
│ │
│ 模型1: XGBoost (主力模型) │
│ ├── 特征: ~100个(用户画像+交易特征+行为统计) │
│ ├── 输出: 风险分(0-1000) + Top3风险因子 │
│ ├── 推理延迟: ~3ms(内存加载,本地推理) │
│ ├── 更新频率: 每周重训 │
│ └── 优势: 快、可解释、对表格数据效果好 │
│ │
│ 模型2: DNN/Transformer (补充模型) │
│ ├── 特征: 用户行为序列(最近50笔交易的Embedding) │
│ ├── 输出: 风险分(0-1000) │
│ ├── 推理延迟: ~8ms(GPU推理/CPU优化后) │
│ ├── 更新频率: 每两周重训 │
│ └── 优势: 能捕捉序列模式(如"先小额试探再大额盗刷") │
│ │
│ 模型融合: │
│ ├── 加权融合: final_score = 0.6×XGB + 0.4×DNN │
│ ├── 模型不一致时: 取较高风险分(宁严勿松) │
│ └── 模型降级: DNN超时→只用XGBoost结果 │
│ │
│ 部署架构: │
│ ┌────────────────────────────────────────────────────┐ │
│ │ Model Serving Layer │ │
│ │ │ │
│ │ XGBoost: 嵌入在风控服务JVM中(最快) │ │
│ │ ├── ONNX Runtime / PMML │ │
│ │ ├── 模型文件<100MB │ │
│ │ └── 无网络开销 │ │
│ │ │ │
│ │ DNN: 独立推理服务(需要GPU) │ │
│ │ ├── TorchServe / ONNX Runtime │ │
│ │ ├── gRPC调用 ~5ms网络开销 │ │
│ │ └── GPU利用率>70% │ │
│ │ │ │
│ │ 模型更新: │ │
│ │ ├── MLflow Model Registry管理版本 │ │
│ │ ├── A/B测试: 新模型先处理10%流量 │ │
│ │ ├── 金丝雀: 逐步10%→30%→50%→100% │ │
│ │ └── 自动回滚: 误报率>阈值→自动切回旧版本 │ │
│ └────────────────────────────────────────────────────┘ │
│ │
└──────────────────────────────────────────────────────────┘
3.4 决策融合引擎
规则+ML融合决策矩阵:
┌─────────────┬──────────────┬──────────────────────────┐
│ 规则结论 │ 模型风险分 │ 最终决策 │
├─────────────┼──────────────┼──────────────────────────┤
│ 黑名单命中 │ 任意 │ REJECT(规则优先) │
│ 白名单命中 │ <400 │ PASS(一致放行) │
│ 白名单命中 │ ≥400 │ PASS但标记异常(后续关注) │
│ 无明确结论 │ <400 │ PASS │
│ 无明确结论 │ 400-600 │ CHALLENGE(二次验证) │
│ 无明确结论 │ 600-800 │ REVIEW(人工审核) │
│ 无明确结论 │ ≥800 │ REJECT │
│ 频率规则命中│ <400 │ CHALLENGE(规则+模型综合) │
│ 频率规则命中│ ≥400 │ REJECT │
│ 金额规则命中│ <600 │ CHALLENGE │
│ 金额规则命中│ ≥600 │ REJECT │
└─────────────┴──────────────┴──────────────────────────┘
决策优先级: REJECT > REVIEW > CHALLENGE > PASS
CHALLENGE(二次验证)的方式:
├── 短信验证码
├── 人脸识别
├── 安全问题
└── 指纹验证
→ 验证通过→PASS,验证失败/超时→REJECT
3.5 案件系统
案件管理系统:
┌──────────────────────────────────────────────────────────┐
│ Case Management System │
├──────────────────────────────────────────────────────────┤
│ │
│ 案件来源: │
│ ├── REJECT: 自动生成案件(记录拒绝原因) │
│ ├── REVIEW: 进入人工审核队列 │
│ ├── 用户投诉: 被拒绝的用户发起申诉 │
│ └── 事后分析: 异步批量检测发现的可疑交易 │
│ │
│ 案件处理流程: │
│ ┌────────────────────────────────────────────────┐ │
│ │ 新案件 → 自动分派(按类型/优先级/审核员技能) │ │
│ │ │ │ │
│ │ ├── P0(高风险): 立即处理(SLA: 15分钟) │ │
│ │ ├── P1(中风险): 4小时内处理 │ │
│ │ └── P2(低风险): 24小时内处理 │ │
│ │ │ │
│ │ 审核员操作: │ │
│ │ ├── 查看交易详情+用户画像+风险因子 │ │
│ │ ├── 查看AI推荐结论+置信度 │ │
│ │ ├── 决策: 确认欺诈 / 放行 / 需要更多信息 │ │
│ │ └── 标注原因(用于模型训练) │ │
│ │ │ │
│ │ 案件结论: │ │
│ │ ├── 确认欺诈 → 冻结账户/退款/报警 │ │
│ │ ├── 误报 → 放行+更新用户白名单 │ │
│ │ └── 标注数据 → 回流到模型训练集 │ │
│ └────────────────────────────────────────────────┘ │
│ │
│ 数据回流(闭环): │
│ ├── 审核结论 → 作为模型训练的标注数据 │
│ ├── 误报案件 → 分析误报原因→优化规则/模型 │
│ ├── 漏报案件 → 用户投诉/外部渠道发现→补充训练数据 │
│ └── 季度评估 → 模型AUC/规则精准率/误报率的趋势分析 │
│ │
└──────────────────────────────────────────────────────────┘
第四步:深入讨论(10分钟)
4.1 性能优化——如何做到<50ms
50ms延迟分解和优化策略:
总延迟预算: 50ms
┌─────────────────┬──────┬───────────────────────────────┐
│ 环节 │ 耗时 │ 优化手段 │
├─────────────────┼──────┼───────────────────────────────┤
│ 网络传输(内网) │ 2ms │ 同机房部署,避免跨区调用 │
│ 请求解析 │ 1ms │ Protobuf(而非JSON) │
│ 特征获取 │ 8ms │ 并行获取+Redis Pipeline │
│ 规则执行 │ 10ms │ 决策树编译+短路优化 │
│ ML推理 │ 8ms │ XGBoost内嵌+ONNX优化 │
│ 决策融合 │ 2ms │ 简单条件判断 │
│ 结果返回 │ 2ms │ gRPC(而非HTTP) │
│ 异步处理投递 │ 2ms │ Kafka异步发送 │
├─────────────────┼──────┼───────────────────────────────┤
│ 总计 │ 35ms │ < 50ms ✓ │
│ 留余量 │ 15ms │ 应对GC/网络抖动 │
└─────────────────┴──────┴───────────────────────────────┘
关键优化技术:
1. 特征获取并行化
├── 使用CompletableFuture并行发起3个Redis请求
├── 等待最慢的返回(~8ms 而非串行 3+3+3=9ms)
└── Redis Pipeline: 多个GET合并为一次网络往返
2. 规则引擎编译优化
├── 规则发布时: DSL → 编译为决策树(Rete算法)
├── 决策树在内存中执行(纳秒级)
├── 规则更新: 增量编译(只重编译变更的规则)
└── 热点规则(黑/白名单): Redis Bloom Filter(<1ms)
3. ML模型优化
├── XGBoost: ONNX Runtime加载,JVM内推理
│ → 无网络开销,~3ms
├── DNN: ONNX量化(FP32→INT8)
│ → 推理速度↑3x,精度损失<0.1%
├── 批量推理: 相似请求合并(微批次)
└── 降级: DNN超时(>15ms)→只用XGBoost
4. JVM优化
├── GC策略: ZGC(低延迟GC)
├── 预热: 启动时加载模型+预热规则引擎
├── 连接池: Redis/Kafka连接池预建
└── 线程模型: Netty + 异步非阻塞
4.2 误报率控制
误报率 <1% 的保障措施:
1. 模型层面
├── 训练时优化Precision(而非Recall)
├── 定期重训(每周): 避免数据漂移导致误报上升
├── 样本平衡: 正负样本比例校准
└── 特征监控: 特征分布异常→触发重训
2. 规则层面
├── Shadow模式: 新规则先Shadow运行2周
│ → 只记录会被命中的交易,不真正执行
│ → 统计命中率、误报率、漏报率
│ → 达标后再正式启用
├── 灰度发布: 1%→5%→20%→100% 逐步放量
├── 自动关停: 单条规则误报率>3%→自动禁用
└── A/B测试: 新旧规则组并行对比
3. 系统层面
├── 阈值动态调整: 大促期间自动放宽阈值
│ (大促时交易模式异常是正常的)
├── 用户反馈闭环: 用户申诉→快速复核→调整规则
├── 误报日报: 每日统计各规则/模型的误报率
└── 月度Review: 分析Top10误报场景→专项优化
误报率监控仪表板:
├── 实时: 过去1小时的误报率(滑动窗口)
├── 日维度: 各规则/模型的独立误报率
├── 周维度: 误报率趋势(上升还是下降)
└── 告警: 误报率>0.8%→告警, >1%→自动降级规则
4.3 数据模型
-- 风控事件表(核心)
CREATE TABLE risk_event (
id BIGINT PRIMARY KEY,
event_id VARCHAR(64) UNIQUE NOT NULL,
txn_no VARCHAR(64) NOT NULL,
user_id BIGINT NOT NULL,
event_type VARCHAR(20) NOT NULL, -- PAYMENT/TRANSFER/LOGIN
amount BIGINT,
device_id VARCHAR(128),
ip_address VARCHAR(45),
risk_score INT NOT NULL, -- 0-1000
decision VARCHAR(20) NOT NULL, -- PASS/REJECT/REVIEW/CHALLENGE
hit_rules JSON, -- 命中的规则列表
model_scores JSON, -- 各模型分数
top_factors JSON, -- Top3风险因子
latency_ms INT, -- 处理耗时
created_at TIMESTAMP DEFAULT NOW()
);
-- 按天分区,保留90天
-- 规则配置表
CREATE TABLE risk_rule (
id BIGINT PRIMARY KEY,
rule_code VARCHAR(64) UNIQUE NOT NULL,
rule_name VARCHAR(200),
rule_type VARCHAR(20) NOT NULL, -- BLACKLIST/FREQUENCY/AMOUNT/SCENE
rule_expression VARCHAR(2000), -- 规则DSL表达式
action VARCHAR(20) NOT NULL, -- REJECT/REVIEW/CHALLENGE/SCORE
score_delta INT DEFAULT 0, -- 风险分增量
priority INT DEFAULT 100,
status VARCHAR(10) DEFAULT 'ACTIVE', -- ACTIVE/SHADOW/DISABLED
effective_time TIMESTAMP,
expire_time TIMESTAMP,
hit_count BIGINT DEFAULT 0, -- 累计命中次数
false_positive BIGINT DEFAULT 0, -- 累计误报次数
version INT DEFAULT 1,
created_at TIMESTAMP DEFAULT NOW(),
updated_at TIMESTAMP DEFAULT NOW()
);
-- 案件表
CREATE TABLE risk_case (
id BIGINT PRIMARY KEY,
case_no VARCHAR(64) UNIQUE NOT NULL,
event_id VARCHAR(64) NOT NULL,
user_id BIGINT NOT NULL,
case_type VARCHAR(20) NOT NULL, -- REVIEW/APPEAL/MONITORING
priority VARCHAR(5) NOT NULL, -- P0/P1/P2
status VARCHAR(20) NOT NULL, -- PENDING/IN_PROGRESS/RESOLVED
assigned_to BIGINT, -- 审核员ID
conclusion VARCHAR(20), -- FRAUD/FALSE_POSITIVE/INCONCLUSIVE
conclusion_note VARCHAR(500),
resolved_at TIMESTAMP,
sla_deadline TIMESTAMP NOT NULL,
created_at TIMESTAMP DEFAULT NOW()
);
-- 名单表(黑/白/灰)
CREATE TABLE risk_list (
id BIGINT PRIMARY KEY,
list_type VARCHAR(10) NOT NULL, -- BLACK/WHITE/GREY
entity_type VARCHAR(20) NOT NULL, -- USER/DEVICE/IP/CARD
entity_value VARCHAR(256) NOT NULL,
reason VARCHAR(200),
expire_time TIMESTAMP, -- NULL=永不过期
created_at TIMESTAMP DEFAULT NOW(),
UNIQUE KEY uk_list (list_type, entity_type, entity_value)
);
第五步:扩展性设计(5分钟)
5.1 从500万到5亿笔/天
扩展路径:
500万笔/天(当前):
├── 风控服务: 10个实例
├── Redis: 3主3从
├── Flink: 3个Task Manager
├── 均值~60 TPS, 峰值~175 TPS
└── 单中心部署
5000万笔/天:
├── 风控服务: 50个实例
├── Redis Cluster: 扩容到6主6从
├── Flink: 10个Task Manager
├── 规则引擎优化: 决策树编译+布隆过滤器
├── 特征缓存: 热点用户特征本地缓存(LRU, TTL=1s)
└── 双中心部署
5亿笔/天(电商大促):
├── 风控服务: 200个实例(K8s HPA)
├── Redis: 多集群(按用户ID段分割)
├── Flink: 50个Task Manager
├── 模型推理: 独立GPU集群(vLLM/TorchServe)
├── 特征平台: 独立Feature Store(Feast/Tecton)
├── 规则引擎: 分布式规则执行
├── 大促模式: 自动降级策略
│ ├── DNN模型超时→降级为XGBoost
│ ├── 规则数量>阈值→只执行高优先级规则
│ └── 特征获取超时→使用默认值(而非等待)
└── 多Region部署(中国/东南亚/欧洲)
5.2 熔断降级策略
风控系统降级策略(核心原则: 风控不可用时不能阻塞交易):
┌──────────────────────────────────────────────────────────┐
│ Degradation Strategy │
├──────────────────────────────────────────────────────────┤
│ │
│ Level 0: 全功能模式(正常) │
│ ├── 规则+ML全部执行 │
│ └── P99<50ms │
│ │
│ Level 1: 轻量模式(部分降级) │
│ 触发条件: P99>80ms 或 ML模型超时>10% │
│ ├── 关闭DNN模型,只用XGBoost │
│ ├── 关闭低优先级规则(只保留名单+频率) │
│ └── P99<30ms │
│ │
│ Level 2: 紧急模式(大幅降级) │
│ 触发条件: P99>100ms 或 Redis部分不可用 │
│ ├── 只执行黑名单检查 │
│ ├── 其他交易直接PASS │
│ └── 异步补充风控(事后分析) │
│ │
│ Level 3: 旁路模式(完全降级) │
│ 触发条件: 风控服务完全不可用 │
│ ├── 交易系统跳过风控调用 │
│ ├── 所有交易记录到Kafka │
│ ├── 风控恢复后异步批量检查 │
│ └── 发现高风险→事后冻结+联系用户 │
│ │
│ 自动恢复: │
│ ├── 降级后每30秒发探测请求 │
│ ├── 连续3次正常→自动升级 │
│ └── Level 3→2→1→0 逐级恢复 │
│ │
└──────────────────────────────────────────────────────────┘
面试官追问及应对
追问1: "Flink特征计算有延迟,如何保证特征的准确性?"
Flink特征延迟问题与解决:
问题: Flink滑动窗口有~30秒延迟
→ 用户1分钟内交易了5次,但Flink可能只算到3次
解决方案: 三层特征补偿
Layer 1: Flink预计算(基础值)
├── 每分钟输出一次聚合结果到Redis
└── 延迟: ~30秒-1分钟
Layer 2: 风控服务本地补偿(增量)
├── 风控服务维护一个本地计数器
│ Map<userId, AtomicLong> recentTxnCount
├── 每次风控请求+1
├── 与Flink数据合并: 最终值 = Flink值 + 本地增量
└── 延迟: 0(实时)
Layer 3: 定期校准
├── Flink输出新值时→重置本地计数器
├── 避免累积误差
└── 校准频率: 每分钟
效果:
├── 准确率: >99%(vs 纯Flink的~95%)
├── 延迟: 0ms(本地内存读取)
└── 代价: 风控服务有状态(需要处理重启)
→ 解决: 重启时从Redis加载最新Flink值
追问2: "新型欺诈模式ML模型没见过怎么办?"
应对新型欺诈(Zero-day Fraud):
1. 异常检测模型(无监督)
├── 不依赖历史标签
├── 检测偏离正常行为模式的交易
├── 模型: Isolation Forest / AutoEncoder
├── 优势: 能发现"从未见过"的异常
└── 劣势: 误报率较高→用于辅助而非主判断
2. 规则引擎快速响应
├── 发现新模式后: 风控运营立即配置新规则
├── 规则<1分钟生效(vs 模型重训需要1周)
├── 先用规则"堵住",再慢慢训练模型
└── 这就是规则+ML混合架构的核心价值
3. 实时告警机制
├── 统计监控: 某时段拒绝率突然上升→告警
├── 聚类分析: 自动聚类可疑交易→发现模式
├── 外部情报: 行业安全社区/黑产监控
└── 人工经验: 资深风控分析师的直觉
4. 快速迭代
├── 标注新样本: 案件系统快速标注
├── 增量训练: 在现有模型上追加训练
├── 快速发布: A/B测试→灰度→全量(1-2天)
└── 模型热更新: 不停服务更新模型文件
本质:
规则引擎 = "已知的已知"(Known Known)
ML模型 = "已知的未知"(Known Unknown)
异常检测 = "未知的未知"(Unknown Unknown)
三者结合才是完整的风控体系。
完整答案总结
实时风控系统设计核心:
1. 特征是基础: 离线(T+1)+近线(分钟)+在线(实时)三层特征
→ 并行获取,Redis存储,Flink流计算
2. 规则+ML混合: 规则处理已知模式(快+可控),ML检测未知模式(准+泛化)
→ 规则优先级高于ML,规则可秒级生效
3. 50ms极致优化: 并行特征获取+编译规则引擎+模型内嵌+gRPC通信
→ 每个环节都要优化,没有单一银弹
4. 误报率<1%: Shadow模式验证+灰度发布+自动关停+用户反馈闭环
→ 宁可漏报也不能高误报(否则影响GMV)
5. 案件闭环: 审核结论→回流训练数据→模型迭代→效果提升
→ 数据飞轮是风控系统持续进化的核心
6. 降级策略: 4级降级(全功能→轻量→紧急→旁路)
→ 风控不可用时不能阻塞交易