多级缓存需在Map基础上叠加控制逻辑,不能简单堆叠;应分层明确职责:本地缓存负责毫秒响应,Redis保障跨节点一致性,DB为唯一可信源;通过装饰器模式封装各层为独立CacheProvider组件,MultiLevelCache按fallback顺序调用;所有联动必须显式编码,禁止自动传播;过期与驱逐需分层梯度配置。

Map 本身不具备层级感知能力,它只是一个键值对容器。要实现“本地快 + 远程稳 + 自动降级”的多级缓存联动,必须在 Map 基础上叠加控制逻辑,不能直接把多个 Map 简单堆叠。
明确各层职责,避免职责混淆
本地缓存(如 Caffeine 或自建 LRU Map)负责毫秒级响应,不承担数据一致性保障;远程缓存(如 Redis)负责跨节点共享与最终一致性;数据库是唯一可信源。三层不是并列关系,而是有明确 fallback 顺序和写入流向:
- 读请求优先查本地缓存 → 未命中则查 Redis → 再未命中才查 DB,并反向写入 Redis 和本地缓存
- 写请求必须穿透到 DB,成功后主动失效或更新 Redis,再按策略决定是否刷新本地缓存(通常异步或延迟刷新)
- 本地缓存不监听 Redis 变更,避免引入复杂的一致性同步逻辑
用装饰器模式串联层级,而非嵌套 Map
不要用 map[string]map[string]interface{} 这类结构模拟层级——它无法表达“查不到就往下走”的行为语义。正确做法是将每层封装为独立组件,通过接口统一:
- 定义 CacheProvider 接口:含 Get(key), Set(key, val, ttl), Delete(key)
- 本地缓存实现该接口,内部用带过期时间的 sync.Map 或 LRU 结构
- Redis 缓存实现同一接口,底层调用 redis.Client
- 最外层写一个 MultiLevelCache,构造时注入本地、Redis 实例,在 Get 方法里按顺序调用,命中即返回并短路后续调用
关键联动点需手动控制,不可依赖 Map 自动传播
Map 不会自动把 set 操作同步到下一层。所有联动必须显式编码:
- 本地缓存 set 时,不自动触发 Redis 写入;只有业务层明确调用 multiCache.Set() 才执行全链路写入
- Redis 删除操作后,本地缓存可选择立即 clear 对应 key,或设置为“懒清除”(下次 get 时发现不一致再丢弃)
- 为防雪崩,本地缓存 miss 后回源加载时,应对相同 key 的并发请求做 singleflight 合并,避免重复穿透 DB
过期与驱逐必须分层独立配置
各层过期时间要有梯度设计,不能全设成一样:
- 本地缓存 TTL 一般设为 1–5 分钟,短于 Redis(如 30 分钟),确保它先过期,促使流量自然回归远程层做一致性校验
- 本地缓存若用 LRU,容量上限要严格限制(如 1000 条),防止内存失控;sync.Map 类型需自行加 expiration 字段,不能只靠 map[key] = value
- Redis 层建议开启 LFU 或 volatile-lru 驱逐策略,而本地层用 LRU 更合适——二者目标不同,不可复用同一套淘汰逻辑

















