前言
最近看到redis的时候,发现有如下疑问:什么是redis雪崩、穿透和击穿?产生这些问题该怎么办?
缓存雪崩
是什么
如果你在使用redis的时候,遇到如下两种情况,可能你就遇到缓存雪崩了。
情况一
系统A,每天高峰并发量每秒5000个请求,缓存可以抗住4000请求,但是这时redis宕机了,此时每秒5000个请求的压力都到了数据库中,数据库必然扛不住,然后就挂了。就算是DBA重启数据库,仍然会新的流量给打死,这就是缓存雪崩了
情况二
系统B,每天高峰并发量每秒5000个请求,缓存可以抗住4000请求,这时所有的key值失效了,也就是过期时间到了,这时每秒5000个请求的压力都到了数据库中,数据库必然扛不住,也会挂掉。这也是缓存雪崩。
该如何解决呢?
如果你在使用redis的时候,遇到如下两种情况,可能你就遇到缓存雪崩了。
缓存雪崩的事前、事中、事后的解决方案:
- 事前:redis高可用,主从+哨兵,redis cluster,避免全盘崩溃。
- 事中:本地ehcache缓存+Hystrix限流/降级,避免MySQL被打死。
- 事后:redis持久化,一旦重启,自动从磁盘上加载数据,快速恢复缓存数据。
- 其他解决方法:java锁实现限流、数据预热、给缓存的失效时间,加上一个随机值,避免集体失效、做二级缓存,或者双缓存策略、缓存永不过期
参考资料:解决redis缓存穿透和缓存雪崩
用户发送一个请求,系统受到请求后,先查本地ehcache缓存,如果没查到再查redis。如果ehcache和redis都没有,再查数据库,将数据库中的结果,写入ehcache和redis中。
限流组件,可以设置每秒的请求,有多少能通过组件,剩余的未通过的请求,怎么办?走降级!可以返回一些默认的值,或者友情提示,或者空白的值。
好处:
- 数据库绝对不会死,限流组件确保了每秒只有多少个请求能通过。
- 只要数据库不死,就是说,对用户来说,2/5的请求都是可以被处理的。
- 只要有2/5的请求可以被处理,就意味着你的系统没死,对用户来说,可能就是点击几次刷不出来页面,但是多点几次,就可以刷出来一次。
缓存穿透
是什么
对于系统A,假设每秒5000个请求,结果其中4000个请求是黑客发来的恶意攻击。那4000个请求在缓存中查询不到,然后进入到数据库中也查询不到。请求每次都“视缓存于无物”,直接查询数据库,也能直接把数据库打死。
该如何解决呢?
- 每次系统A从数据库中查询不到,就写一个空值到缓存里去,以请求参数为key,null值为value,设置过期时间,这样下次有相同的key来访问的时候,在缓存失效之前,都可以直接从缓存中取数据。
- 设置布隆过滤:将所有可能存在的数据哈希到一个足够大的bitmap中,一个一定不存在的数据会被这个bitmap拦截掉,从而避免了对底层数据库的查询压力。
缓存击穿
是什么
缓存击穿,就说某个热点key,访问非常频繁,处于集中式高并发访问的情况,当这个key在失效的瞬间,大量的请求就击穿了缓存,直接访问数据库,就像是在一道屏障上凿开了一个洞。
该如何解决呢?
- 将热点数据设置为永不过期
- 基于redis 或者 zookeeper 实现互斥锁,等待第一个请求构建完缓存之后,再释放锁,进而其他请求才能通过该key访问数据。
黑色背景 |
小结
有关redis的内容,在继续深入的过程中,加深理解。明白为什么,该如何做。
感谢您的阅读~~