3、特征服务架构设计:在线特征服务 vs 离线特征服务、特征缓存策略、高并发读取设计

在额度定价决策链路中,特征服务是连接原始数据与模型推理的桥梁。本章聚焦特征服务的架构选型、缓存策略与高并发读取设计,帮助你在延迟、吞吐与一致性之间找到最佳平衡点。

3.1 在线特征服务 vs 离线特征服务

特征服务按时效性可分为在线(Online)与离线(Offline)两类,它们在数据源、计算模式、存储介质和服务目标上存在本质差异。

对比维度 在线特征服务 离线特征服务
数据时效 实时/准实时(秒级~分钟级) T+1 或小时级批量
数据源 Kafka、Redis、实时数据库 Hive、HDFS、数据湖
计算模式 流式计算(Flink/Spark Streaming) 批处理(Spark/MapReduce)
存储介质 Redis Cluster、Memcached、本地缓存 Parquet/ORC 文件、HBase
典型延迟 < 10ms(P99) 分钟~小时级
使用场景 实时风控、在线定价、实时推荐 模型训练、离线分析、批量评分
架构建议:在额度定价场景中,建议采用 Lambda 架构——离线特征用于模型训练与回溯验证,在线特征用于实时决策。两者共享特征定义,但存储与计算链路完全隔离。

3.2 特征缓存策略

缓存是降低在线特征服务延迟的核心手段。合理的缓存策略需要平衡命中率、一致性、内存开销与更新频率。

3.2.1 缓存分层模型

推荐采用三级缓存架构:本地堆内缓存 → 分布式缓存 → 特征存储,逐级回退。

  • L1 本地缓存(Caffeine/Guava):毫秒级访问,适用于高频访问且变化不频繁的特征(如用户基础画像)。
  • L2 分布式缓存(Redis Cluster):亚毫秒级,适用于跨服务共享的特征(如设备指纹、历史逾期标签)。
  • L3 特征存储(HBase/MySQL):持久化层,作为兜底数据源,仅在缓存 Miss 时访问。

3.2.2 缓存更新策略对比

策略 机制 一致性 适用场景
TTL 过期 写入时设置过期时间,到期自动失效 弱一致 变化缓慢的特征(如性别、年龄)
主动失效 特征变更时发送失效消息,各节点清除缓存 最终一致 实时更新的特征(如额度使用率)
写穿透 更新数据库时同步更新缓存 强一致 关键决策特征(如黑名单状态)
异步刷新 后台定时批量拉取最新特征,预热缓存 弱一致 批量特征(如征信报告摘要)
避坑提示:避免使用“缓存穿透”策略——当大量请求同时查询一个不存在的 key 时,会直接打穿到数据库。建议对空结果也做短暂缓存(空值缓存),或使用布隆过滤器前置拦截。

3.3 高并发读取设计

在线特征服务需要支撑每秒数万甚至数十万次查询,且 P99 延迟必须控制在 10ms 以内。以下是经过生产验证的高并发设计要点。

3.3.1 连接池与线程模型

  • 连接池复用:对 Redis、数据库等后端资源使用连接池(如 HikariCP、Jedis Pool),避免频繁创建/销毁连接。
  • 异步非阻塞 I/O:采用 Netty 或 Vert.x 等异步框架,减少线程上下文切换开销。
  • 协程/纤程:在 Java 虚拟线程或 Kotlin 协程中执行特征读取,提升吞吐量。

3.3.2 批量读取与管道化

单次请求获取多个特征时,使用 mget(Redis)或 批量查询(HBase)合并网络往返。对于跨多个特征源的场景,采用 并行调用 + 超时熔断 模式。

// 伪代码:并行批量读取特征
CompletableFuture<FeatureResult> future1 = featureClient.batchGetAsync(userId, "profile", "credit");
CompletableFuture<FeatureResult> future2 = featureClient.batchGetAsync(userId, "risk", "fraud");

FeatureResult result = CompletableFuture
    .allOf(future1, future2)
    .thenApply(v -> merge(future1.join(), future2.join()))
    .get(50, TimeUnit.MILLISECONDS); // 超时熔断

3.3.3 读写分离与副本扩展

对于 Redis Cluster 或 HBase,采用 读写分离 架构:写入主节点,读取从节点或副本。在流量高峰期,动态增加从节点副本以水平扩展读取能力。

生产指标参考:某头部消费金融公司在线特征服务,采用三级缓存 + 异步批量读取后,P99 延迟从 45ms 降至 6ms,QPS 从 8k 提升至 65k,缓存命中率稳定在 98.7% 以上。

3.4 架构总览:在线特征服务流程

下图展示了在线特征服务的核心架构与数据流,涵盖缓存分层、批量读取与高并发设计的关键节点。

在线特征服务架构图 在线特征服务架构图 客户端请求 负载均衡 / API Gateway 在线特征服务(异步非阻塞) 三级缓存架构 L1 本地缓存 (Caffeine) L2 分布式缓存 (Redis) L3 特征存储 (HBase) 命中率 ~80% 命中率 ~18% 兜底查询 ~2% 批量读取(mget) + 并行调用 + 超时熔断(50ms)

3.5 离线特征服务流程

离线特征服务以批处理方式生成特征,供模型训练与离线评估使用。其核心流程包括特征计算、存储与版本管理。

离线特征服务流程图 离线特征服务流程图 原始数据源 Hive / Kafka / 数据湖 批处理引擎 Spark / Flink Batch 特征存储 Parquet / HBase 特征版本管理 模型训练 XGBoost / DNN 离线评估 AUC / KS / 回溯测试 特征回溯 时间旅行 / 快照 离线特征通常按天分区,保留 30~90 天历史快照,支持时间旅行查询

3.6 特征服务选型决策矩阵

在实际项目中,需要根据业务场景、数据特征与性能要求,选择合适的特征服务架构。下表总结了关键决策因素。

决策因素 倾向在线特征 倾向离线特征 混合架构
延迟要求 < 20ms > 1s 在线 < 10ms,离线无要求
数据更新频率 秒级~分钟级 天级 实时特征在线,静态特征离线
特征数量 < 500 个/请求 数千~数万 在线只取关键特征
一致性要求 最终一致可接受 强一致 关键特征强一致
成本预算 高(内存/SSD) 低(HDFS/对象存储) 按特征分级存储
最佳实践:在额度定价场景中,建议将特征分为三类:
热特征(实时额度使用率、当前逾期状态)→ 在线服务 + L1/L2 缓存;
温特征(近 30 天消费均值、历史最大额度)→ 在线服务 + L2 缓存;
冷特征(征信报告摘要、人口统计信息)→ 离线预计算,每日同步至在线存储。