缓存雪崩
- 缓存机器宕机,缓存无法使用,请求全部落数据库,数据库一般扛不住,然后数据库也宕机,导致服务彻底不可用;就算重启数据库,在高并发情况下,很快又会宕机
- 解决方案:
- 事前:redis 高可用,主从 + 哨兵,redis cluster,避免全盘崩溃
- 事中:本地 ehcache 缓存 + hystrix 或 sentinel 限流&降级,避免 MySQL 宕机
- 事后:redis 持久化,一旦重启,自动从磁盘上加载数据,快速恢复缓存数据
缓存穿透
- 对于大部分的请求的数据,在数据库中根本就不存在,每次查询的时候,先到缓存中查,缓存中没有再到数据库中查,如果查询的数在数据库中根本不存在,那么每次查询都会到数据库中查询,穿透过缓存去查数据库,视缓存于无物
- 解决方案:
- 设置空值:每次请求读取的时候,读取不到值的 key,就设置空值,这样只要缓存没失效,就能够防止直接去查数据库
- 布隆过滤器:能够对访问的请求起到一定的初筛作用,避免因数据不存在引起的查询压力,将要查询的数据映射到过滤器中,如果过滤器中不存在就一定不存在
缓存击穿
- 某些 key 非常热点,访问非常频繁,处于集中式高并发访问的情况,当这个 key 在失效的瞬间,大量的请求就击穿缓存,直接请求数据库
- 解决方案
- 缓存基本不变更:设置永不过期
- 更新不频繁、缓存刷新耗时少:采用基于 redis、zookeeper 等分布式中间件的分布式互斥锁,或者本地互斥锁以保证仅少量的请求能请求数据库并重新构建缓存,其余线程则在锁释放后能访问到新缓存
- 更新频繁、缓存刷新耗时长:利用定时线程在缓存过期前主动地重新构建缓存或者延后缓存的过期时间,以保证所有的请求能一直访问到对应的缓存