跳到主要内容

缓存策略

目录

  1. 引言
  2. 项目结构
  3. 核心组件
  4. 架构总览
  5. 详细组件分析
  6. 依赖关系分析
  7. 性能考量
  8. 故障排查指南
  9. 结论
  10. 附录

引言

本文件面向规则引擎的缓存策略,系统性阐述三级缓存架构(本地缓存、Redis缓存、数据库缓存)的设计与实现,覆盖缓存穿透防护、分布式锁、缓存失效与更新机制、不同数据类型的缓存策略、性能监控与调优、配置参数与故障处理,以及最佳实践与常见问题。

项目结构

规则引擎缓存相关代码主要分布在以下模块与包:

  • 规则API模块:缓存Key定义、Redis读写DAO、运行时查询工具、事件与监听
  • 框架Redis模块:本地缓存封装、分布式锁、缓存自动装配与配置

Mermaid Diagram Code:

graph TB
subgraph "规则引擎"
A["RuleRunUtil<br/>三级缓存查询"]
B["ApiLiteflowChainRedisDAO<br/>Redis读写"]
C["CacheConstants<br/>缓存Key常量"]
D["RuleLiteflowChainCacheDTO<br/>规则详情DTO"]
E["LocalCacheClearEventListener<br/>本地缓存清理事件监听"]
F["RuleApiUtil<br/>事件发布/广播"]
end
subgraph "框架Redis"
G["LocalCacheUtils<br/>本地缓存封装"]
H["RedisDistributionLockUtils<br/>Redis分布式锁"]
I["YudaoCacheAutoConfiguration<br/>缓存自动装配"]
J["YudaoCacheProperties<br/>缓存配置"]
end
A --> B
A --> G
A --> H
B --> C
B --> D
E --> G
F --> E
I --> J

图表来源

章节来源

核心组件

  • 本地缓存:基于Caffeine的本地缓存管理器,用于热点数据的低延迟访问与减轻远端压力
  • Redis缓存:多维度Key设计,支撑规则ID集合、规则详情、业务限制等缓存
  • 数据库缓存:作为最终一致性保障,在缓存未命中时兜底查询
  • 分布式锁:Redis实现的互斥锁,用于缓存穿透防护与热点数据重建
  • 事件广播:Spring Cloud Bus广播本地缓存清理事件,实现多实例缓存一致性

章节来源

架构总览

规则引擎采用“本地缓存优先、Redis兜底、数据库保底”的三级缓存策略;通过分布式锁与占位符实现缓存穿透防护;通过事件广播实现多实例本地缓存的延迟清理,避免同时失效引发的击穿。

Mermaid Diagram Code:

graph TB
Client["客户端/业务系统"] --> RunUtil["RuleRunUtil<br/>三级缓存查询"]
RunUtil --> Local["LocalCacheUtils<br/>本地缓存"]
RunUtil --> RedisDAO["ApiLiteflowChainRedisDAO<br/>Redis读写"]
RedisDAO --> Redis["Redis"]
RedisDAO --> |未命中/穿透| Lock["RedisDistributionLockUtils<br/>分布式锁"]
Lock --> DB["数据库查询"]
DB --> RedisDAO
RedisDAO --> LocalEvict["RuleApiUtil<br/>广播事件"]
LocalEvict --> Bus["Spring Cloud Bus"]
Bus --> Listener["LocalCacheClearEventListener<br/>延迟清理本地缓存"]
Listener --> Local

图表来源

详细组件分析

三级缓存查询流程(规则详情)

规则详情的查询顺序为:本地缓存 → Redis → 数据库;若数据库也无数据,则写入穿透占位符,避免缓存穿透风暴。

Mermaid Diagram Code:

sequenceDiagram
participant Caller as "调用方"
participant Util as "RuleRunUtil"
participant Local as "LocalCacheUtils"
participant RedisDAO as "ApiLiteflowChainRedisDAO"
participant Lock as "RedisDistributionLockUtils"
participant DB as "数据库"
Caller->>Util : getRuleDetailWithLocalCache(ruleId)
Util->>Local : 读取本地缓存
alt 命中且非穿透占位符
Local-->>Util : 返回规则详情
Util-->>Caller : 返回结果
else 未命中或穿透占位符
Util->>RedisDAO : 从Redis读取
alt Redis命中且非穿透占位符
RedisDAO-->>Util : 返回规则详情
Util-->>Caller : 返回结果
else Redis未命中
Util->>Lock : 加分布式锁
Lock-->>Util : 获取锁成功
Util->>RedisDAO : 再查Redis双重检查
alt 再查命中
RedisDAO-->>Util : 返回规则详情
Util-->>Caller : 返回结果
else 再查仍未命中
Util->>DB : 查询数据库
DB-->>Util : 返回规则详情
Util->>RedisDAO : 写入Redis含随机过期
Util-->>Caller : 返回结果
end
Util->>Lock : 释放锁
end
end

图表来源

章节来源

缓存穿透防护机制

  • 占位符设计:当数据库查询为空时,写入特定占位符(如规则详情的空占位符、业务限制的空占位符),并在读取时识别并视为未命中
  • 分布式锁:在缓存未命中时加锁,再次检查缓存,避免多个请求同时打穿数据库
  • 随机过期:写入Redis时使用随机过期时间,降低缓存雪崩风险

Mermaid Diagram Code:

flowchart TD
Start(["开始"]) --> CheckLocal["检查本地缓存"]
CheckLocal --> LocalHit{"本地命中?"}
LocalHit --> |是| IsPenetrateLocal{"是否为穿透占位符?"}
IsPenetrateLocal --> |是| ToRedis["去Redis查询"]
IsPenetrateLocal --> |否| ReturnLocal["返回本地缓存"]
LocalHit --> |否| ToRedis
ToRedis --> RedisHit{"Redis命中?"}
RedisHit --> |是| IsPenetrateRedis{"是否为穿透占位符?"}
IsPenetrateRedis --> |是| ToDB["去数据库查询"]
IsPenetrateRedis --> |否| ReturnRedis["返回Redis结果"]
RedisHit --> |否| Lock["加分布式锁"]
Lock --> Recheck["双重检查缓存"]
Recheck --> Rehit{"再次命中?"}
Rehit --> |是| ReturnRehit["返回缓存结果"]
Rehit --> |否| QueryDB["查询数据库"]
QueryDB --> DBEmpty{"数据库为空?"}
DBEmpty --> |是| SetPenetrate["写入穿透占位符"]
SetPenetrate --> Unlock["释放锁"]
DBEmpty --> |否| SetCache["写入Redis随机过期"]
SetCache --> Unlock
Unlock --> End(["结束"])

图表来源

章节来源

缓存失效策略

  • 主动失效:通过事件广播触发本地缓存清理,监听器在随机延迟后清理指定缓存键或整个缓存,避免“惊群效应”
  • 被动失效:Redis键自带随机过期时间,降低集中过期引发的抖动
  • 缓存更新:监听数据变更事件,实时更新Redis对应维度的缓存

Mermaid Diagram Code:

sequenceDiagram
participant Producer as "缓存更新生产者"
participant Bus as "Spring Cloud Bus"
participant Listener as "LocalCacheClearEventListener"
participant Local as "LocalCacheUtils"
Producer->>Bus : 发布本地缓存清理事件
Bus-->>Listener : 广播事件
Listener->>Listener : 计算随机延迟(1ms~10s)
Listener->>Local : 延迟清理缓存按cacheName/cacheKey
Local-->>Listener : 清理完成

图表来源

章节来源

不同数据类型的缓存策略

  • 规则详情缓存:Key为规则ID,Value为规则详情DTO;支持穿透占位符与随机过期
  • 业务限制缓存:Key为业务类型+业务ID,Value为业务限制DTO;数量限制实时从Redis读取,避免本地缓存陈旧
  • 规则ID集合缓存:按MAC、业务类型、渠道、无设备限制等维度维护规则ID集合;支持穿透占位符与随机过期

章节来源

缓存Key设计与更新机制

  • Key设计遵循统一前缀与命名规范,涵盖MAC、渠道、业务类型、规则ID、无设备限制等维度
  • 更新机制通过监听数据变更事件,实时更新对应维度的缓存;删除规则时清理相关缓存

章节来源

依赖关系分析

  • RuleRunUtil依赖本地缓存、RedisDAO、分布式锁与数据库接口,形成完整的三级缓存链路
  • ApiLiteflowChainRedisDAO负责Redis读写与Key生成,是缓存数据的唯一入口
  • LocalCacheUtils与YudaoCacheAutoConfiguration共同构成本地缓存基础设施
  • RedisDistributionLockUtils提供分布式锁能力,保障缓存穿透防护与热点重建
  • RuleApiUtil与LocalCacheClearEventListener配合实现多实例本地缓存的一致性

Mermaid Diagram Code:

graph LR
RuleRunUtil --> LocalCacheUtils
RuleRunUtil --> ApiLiteflowChainRedisDAO
RuleRunUtil --> RedisDistributionLockUtils
ApiLiteflowChainRedisDAO --> CacheConstants
ApiLiteflowChainRedisDAO --> RuleLiteflowChainCacheDTO
RuleApiUtil --> LocalCacheClearEventListener
LocalCacheClearEventListener --> LocalCacheUtils
YudaoCacheAutoConfiguration --> YudaoCacheProperties

图表来源

性能考量

  • 本地缓存:Caffeine本地缓存容量与过期策略需结合热点数据特征调优,避免内存占用过高
  • Redis:合理设置随机过期范围,降低集中过期风险;批量扫描与序列化策略影响整体吞吐
  • 缓存穿透:通过占位符与分布式锁控制瞬时流量,避免数据库压力尖峰
  • 事件清理:随机延迟清理避免“惊群效应”,提升多实例稳定性

章节来源

故障排查指南

  • 缓存穿透风暴:确认是否正确写入穿透占位符,检查分布式锁是否释放
  • 本地缓存未更新:确认事件广播是否正常,监听器是否延迟清理
  • Redis过期异常:检查随机过期配置与键空间扫描批次大小
  • 业务限制不一致:确认业务限制从Redis实时读取,避免本地缓存陈旧

章节来源

结论

规则引擎通过三级缓存与完善的穿透防护、失效与更新机制,实现了高并发下的稳定与高性能。结合事件广播与随机延迟清理,确保多实例缓存一致性与系统弹性。建议持续关注热点数据分布、本地缓存容量与Redis过期策略,以进一步优化性能与稳定性。

附录

缓存配置参数说明

  • 随机过期最小/最大秒数:用于Redis键的随机过期范围,降低集中过期风险
  • Redis扫描批次大小:影响批量扫描性能与内存占用
  • 本地缓存容量与过期策略:由本地缓存管理器配置决定

章节来源

缓存Key设计规范

  • 规则详情:data:base:rule: {rule_id}
  • MAC → 规则ID:rⓂ️r: {mac}
  • 业务类型 → 规则ID:r:btype:r: {business_type}
  • 渠道ID → 规则ID:r:c:r: {channel_id}
  • 无设备限制 → 规则ID:r:no:limit:r
  • 规则ID+业务类型 → 业务ID:r:r:btype🅱️ {rule_id}
  • 业务类型 → 业务ID → 数量限制:r:btype🅱️limit: {business_type}

章节来源

用户文档
AI 助手
Agent 列表
请选择一个 Agent 开始对话
AI 问答