缓存穿透
缓存穿透是指客户端的请求数据在缓存和数据库中都不存在,这样缓存永远不会生效,这些请求都会到达数据库,从而导致数据库负载过高。
常见解决方案有两种:
- 缓存空对象:实现简单、方便维护,是解决缓存穿透的首选方法,但会造成额外内存消耗,或短期的数据不一致
- 布隆过滤:内存占用少,没有多余key,但实现复杂且有可能误判
缓存雪崩
缓存雪崩是指在同一时间段大量缓存 key 同时失效或 Redis 服务宕机,导致大量请求到达数据库,导致数据库负载过高。
常见解决方案如下:
- 给不同的 key 的过期时间添加随机值
- 利用 Redis 集群提高服务的可用性
- 给缓存业务添加限流降级策略
- 给业务添加多级缓存
缓存击穿
缓存击穿也叫热点 key 问题,就是一个被高并发访问并且缓存重建业务比较复杂的 key 突然失效了,无数的请求访问会在瞬间给数据库带来巨大的冲击。
常见解决方案有以下两种:
互斥锁
给重建缓存的逻辑加上一个互斥锁,避免多个线程同时访问数据库,这种方法通常应用在一致性要求较高的场景。
逻辑过期
在缓存对象中维护一个过期时间的字段,当查询缓存时发现已过期则获取互斥锁(例如 Redis 中的 setnx)并开启一个新线程重建缓存数据并将释放互斥锁的逻辑放在新线程中,原线程返回过期数据。当在缓存重建时有其他线程访问缓存并发现数据过期时获取互斥锁失败则直接返回过期数据。这种方法通常应用在对可用性较高的场景。