Redis击穿,传统,雪崩和预热
1.缓存穿透
问题:
- Redis服务器中命中率随着时间逐步降低。
缓存穿透的概念很简单,用户想要查询一个数据,发现redis内存数据库没有,也就是缓存没有命中,于是向 持久层数据库查询。发现也没有,于是本次查询失败。当用户很多的时候,缓存都没有命中,于是都去请求了 持久层数据库。这会给持久层数据库造成很大的压力,这时候就相当于出现了缓存穿透。 这里需要注意和缓存击穿的区别,缓存击穿,是指一个key非常热点,在不停的扛着大并发,大并发集中对这 一个点进行访问,当这个key在失效的瞬间,持续的大并发就穿破缓存,直接请求数据库,就像在一个屏障上 凿开了一个洞。 为了避免缓存穿透其实有很多种解决方案。下面介绍几种。 |
当存储层不民众后,即使返回空对象也将其缓存起来,同时设置一个过期时间,之后访问这个数据会直接从缓存中获取,保护了后端数据源;但是需要注意设置过期时间 |
但是这种方法会存在一个问题:即使对空值设置了过期时间,还是会在缓存层和存储层的数据会有一段时间窗口可能不一致,这对于需要保持一致性的业务会有一定得影响
###1.3实施监控
监控命中率(业务正常范围时候,通过会有一个波动值),根据不同的情况设置黑名单 |

缓存雪崩是指,缓存层出现了错误,不能正常工作了。于是所有的请求都会达到存储层,存储层的调用量会暴 增,造成存储层也会挂掉的情况。经常出现的情况是408,500的错误页面. |
Solution:
(1)redis高可用这个思想含义是,既然redis可能挂掉,那么增设几台redis,这样一台挂掉之后其他的还可以继续工作,也就是搭建集群。
(2)限流降级 这个解决方案的思想是,在缓存失效后通过加锁或者队列来控制读数据库写缓存的线程数量。比如对于某个key只允许一个线程查询数据和写缓存。其他线程在这个过程等待。
(3)数据预热 在即将发生大并发访问前手动触发加载缓存不同的key,设置不同的过期时间,让缓存失效的时间点尽量均匀。
3.缓存击穿
缓存击穿是在高并发的条件下读取缓存数据,多用户同时请求一个缓存数据,如果缓存中没有这条数据,那么这些用户又同时去数据库中查询这条数据,浪费了系统资源,有悖于缓存数据的初衷,严重的话可能会造成服务器宕机的风险 |
Solution
(1)使用同步锁,修饰在获取缓存的方法里面,保证在多用户同时请求的条件下,只有第一个进入的线程去判断是否要查询数据库并存入缓存,其他线程只需要在第一个线程结束后,从缓存中读取数据即可,无需再去访问持久性数据库。
上面是对缓存穿透的再次优化,加入线程同步锁以及双重锁检查。
双重锁检查:
1.避免当缓存数据没有失效时,其他线程排队等待。 |
2.当第一个线程从数据库中获取到数据并存入缓存中时,其他线程直接从缓存中获取数据即可 |
问题:
1.主从之间数据吞吐量大
2.数据同步操作频度高
解决方案 1.统计访问频度较高的热点数据,比如直接写个缓存刷新页面,上线时手动操作 2.数据量不大,可以再项目启动时自动进行加载 3.定期刷新缓存