3. 特征缓存入门
在金融推理系统中,特征往往来自多个上游:行情快照、用户画像、风控名单、交易聚合指标。若每次推理都回源计算或查询数据库,延迟与成本都不可接受。特征缓存的核心目标,是把“高成本、可复用”的特征值暂存到离推理引擎更近的位置,用空间换时间,用副本换稳定。
一、缓存的基本概念与命中率
缓存本质是一个键值存储层,键通常是“实体ID+特征名+时间窗口”,值是该特征在某一时刻的快照。读取时先查缓存,命中则直接返回;未命中则回源加载并写回缓存。衡量缓存效果最关键的指标是命中率:
命中率 = 命中次数 / (命中次数 + 未命中次数)
回源率 = 1 - 命中率
命中率并非越高越好。金融场景中,过期特征若被继续命中,会直接导致错误决策。因此需要同时关注“命中质量”,即命中值是否仍在业务允许的有效期内。常见缓存策略包括:
- TTL 过期:为每个特征设置生存时间,适合行情、汇率等时效敏感数据。
- LRU/LFU 淘汰:内存有限时按最近使用或使用频率淘汰,适合用户画像类特征。
- 主动刷新:后台定时或事件驱动更新,适合名单类、黑名单类特征。
- 写穿透与写回:写穿透保证缓存与源一致但延迟高;写回性能好但存在丢失风险。
二、缓存穿透、击穿与雪崩
这三类问题在金融推理中表现尤为剧烈,因为一次异常可能触发大量并发推理请求。
| 问题 | 触发原因 | 典型表现 | 应对策略 |
|---|---|---|---|
| 缓存穿透 | 查询不存在的键,缓存与源都没有 | 每次请求都打到数据库 | 空值缓存、布隆过滤器、参数校验 |
| 缓存击穿 | 热点键过期瞬间大量并发回源 | 单点压力骤增,源库被打挂 | 互斥锁重建、逻辑过期、热点永不过期 |
| 缓存雪崩 | 大量键同时过期或缓存节点故障 | 整体回源,系统级联失败 | TTL 加随机抖动、多级缓存、熔断降级 |
金融场景中,缓存雪崩常与“整点批量刷新”同时出现。例如所有行情特征在 09:30 统一过期,开盘瞬间回源量可能达到平峰的数十倍。必须为 TTL 增加随机偏移,并保留本地二级缓存作为缓冲。
三、金融场景下特征缓存的特殊需求
与推荐、搜索等场景不同,金融推理对缓存提出更严苛的要求:
- 强时效性:行情、盘口、汇率等特征的有效期可能只有毫秒到秒级,过期即不可用。
- 一致性优先:风控名单、限额、持仓等特征若读到旧值,可能造成超额交易或合规风险。
- 可追溯与审计:每次推理使用了哪个版本的特征、何时写入、来源何处,都必须可回溯。
- 隔离性:不同业务线、不同客户的特征缓存需要逻辑或物理隔离,避免相互污染。
- 降级可控:缓存不可用时,系统应能按预设策略降级,而不是直接崩溃或返回错误特征。
一个实用的判断原则:如果特征读错会导致资金损失或合规问题,就应视为“强一致特征”,优先走源库或带版本校验的缓存;如果只是影响排序或体验,才可接受最终一致。
四、案例:行情特征缓存的雪崩复盘
某量化推理服务在开盘时出现大面积超时。排查发现,所有股票的“最新价”特征使用了统一 TTL=60s,且写入时间集中在同一秒。开盘后第 60 秒,数百万键同时过期,推理请求全部回源到行情网关,网关连接池耗尽,进而拖垮整个推理链路。
# 问题配置示例
feature: latest_price
ttl: 60s
refresh: batch_at_startup
# 修复后配置
feature: latest_price
ttl: 60s
ttl_jitter: 15s # 随机抖动,避免同时过期
local_cache: true # 本地二级缓存
fallback: last_known # 降级返回最近已知值并标记 stale
修复后,TTL 在 45~75 秒之间随机分布,回源压力被摊平;本地缓存承接了大部分瞬时读;降级策略保证即使回源失败,推理仍可继续,只是特征被标记为“可能过期”。
五、常见误区与复盘要点
- 误区一:命中率越高越好。 若命中的是过期特征,高命中率反而放大错误。应同时监控“过期命中率”。
- 误区二:所有特征用同一 TTL。 行情、画像、名单的时效差异巨大,统一 TTL 必然导致部分特征过旧或频繁回源。
- 误区三:忽略缓存版本。 特征值更新后,旧版本可能仍在缓存中。应写入版本号或时间戳,推理时校验。
- 误区四:没有降级预案。 缓存故障时直接报错,会中断整个推理链路。应预设 last_known、默认值或跳过该特征。
本节核心结论:特征缓存不是简单的“加一层 Redis”,而是要在命中率、时效性、一致性与可用性之间做显式权衡。理解穿透、击穿、雪崩的触发条件,并针对金融场景建立版本校验、TTL 抖动、多级缓存与降级策略,才能让缓存真正服务于稳定、可审计的金融推理。