Redis 缓存策略:Cache Aside、过期与击穿防护
缓存的核心不是把数据放进 Redis,而是定义数据何时读取、何时失效以及短暂不一致是否可接受。不同业务对实时性和可用性的要求不同,因此需要先确定权威数据源和一致性边界。
核心原则
- Cache Aside 读取先查缓存,未命中再读数据库并回填;数据库始终是权威来源。
- 写入通常先更新数据库再删除缓存,并用监控或消息补偿异常删除。
- TTL 加入随机抖动,避免大量键在同一时刻过期形成缓存雪崩。
- 热点键重建使用互斥、单飞或逻辑过期,避免大量请求同时穿透数据库。
- 对不存在的数据使用短时空值或布隆过滤器,但要评估误判和更新成本。
推荐的实践步骤
设计键名时包含业务域、对象标识和结构版本,例如 user:v2:1024。序列化内容只保留读路径需要的字段,TTL 由数据变化频率决定。上线时重点监控命中率、回源 QPS、热点键、内存淘汰和命令延迟,并通过降级保护数据库。
value = redis.get(key)
if value is None:
with singleflight(key):
value = redis.get(key)
if value is None:
value = database.load(user_id)
redis.set(key, encode(value), ex=random_ttl())
return decode(value)
示例用于说明实现思路,实际项目还应结合所使用的框架版本、部署环境和业务约束进行调整。重要配置要进入版本管理,并在测试环境验证后再发布。
常见误区
- 所有数据都设置相同 TTL,容易在整点产生集中失效。
- 数据库更新后只更新缓存不更新权威数据,会让一致性模型难以维护。
- 把 Redis 当作无限容量存储而不设置淘汰和大键监控,可能阻塞实例。
上线前检查清单
- 确认“Cache Aside 读取先查缓存,未命中再读数据库并回填;数据库始终是权威来源”已经通过代码审查或运行验证。
- 确认“写入通常先更新数据库再删除缓存,并用监控或消息补偿异常删除”已经通过代码审查或运行验证。
- 确认“TTL 加入随机抖动,避免大量键在同一时刻过期形成缓存雪崩”已经通过代码审查或运行验证。
- 确认“热点键重建使用互斥、单飞或逻辑过期,避免大量请求同时穿透数据库”已经通过代码审查或运行验证。
- 为失败路径、边界条件和回滚方案准备测试或演练记录。
- 上线后观察错误率、延迟和资源消耗,确认变化符合预期。
总结
Redis 缓存策略:Cache Aside、过期与击穿防护的关键在于把隐含假设变成可执行的约束,并通过测试、监控和复盘持续验证。先从影响最大的真实场景开始,小步调整并保留回滚能力,通常比一次性大范围改造更安全,也更容易积累可复用的工程经验。