Redis缓存 雪崩、穿透、击穿?
Redis正常的缓存流程
当用户访问淘宝数据时,淘宝会去访问Redis缓存数据库查看是否有该数据的缓存
如果有,就直接返回
如果没有,就去数据库进行查询
查询到结果过后直接返回给淘宝,并且将查询的结果数据同步到redis缓存数据库中
Redis缓存雪崩【redis缓存的中的key同时失效(过期)】
对于淘宝来说,双十一的访问量是很大的,会将数据存放在redis中缓存起来,假如redis可以存100个key【redis采用键值对的方式进行存储】,缓存时间为3个小时【3小时过期】,当超过3个小时时,这100个redis缓存的key在同一时间全部失效,从而100个key上的全部请求打到数据库。造成数据库挂掉。这样首页就不能对外进行服务了。
简单来说,就是大量的redis同一时间大面积的失效,大量的请求直接打到数据库上【导致数据库压力飙升】,这种现象就是缓存雪崩
如何解决Redis雪崩呢?
1设置redis的缓存时间,不要让他们在同一时间失效,在我们设置redis缓存的时候,随机初始化他的失效时间,这样就不会在同一时间失效,导致所有请求全部打到数据库上**
2采用熔断机制/服务降级(针对不同的数据采用不同的处理方式),直接返回预先设置好的兜底数据。
2redis一般是集群部署(多个服务器处理相同的业务)【就是主服务器的数据可以同步到从服务器上,从服务器还可以关联其他主服务器】,我们将这些 热点的key 放在不同的节点,将这些热点的redis缓存平均的分布在不同的redis节点上
3【暴力方法】不设置失效时间,---但是比较占用空间和内存。【解决-使用定时任务TimerTask做定时,在3小时之前,重新将redis再设置3,这样就永远不会失效】
Redis缓存穿透【缓存和数据库都找不到数据】
缓存穿透:用户访问的数据在Redis缓存中和数据库中都没有这样的数据,然后用户不断地使用脚本发送这个请求【数据库中的id是自增长从0开始的,没有负数】,这种数据直接穿透缓存,打到数据库上,导致数据库挂掉。
解决方案:
1 使用Hystrix熔断器,采用熔断机制和降级策略,当数据库和缓存中都查询不到这个数据时,直接返回一个兜底数据(就是对于数据库和缓存中都查询不到的值,直接返回一个提示信息或null),并将兜底数据同步到缓存中。
这个请求不管在数据库中是否查到都要返回一个结果同步给redis,下次同样的请求再次来的时候,直接返回redis中的结果给淘宝,就不再访问数据库。【但是它会换成另一个请请求?】
2将这个ip进行拉黑(因为有可能是使用脚本故意在攻击数据库)【但是它可以换不同的ip】
3通过对参数的合法性校验,判断这个参数不合法的时候,直接return掉
4使用布隆过滤器【这个最好】
Redis缓存击穿【热点redis失效】
Redis缓存击穿:
指的是Redis中一个热点Key,在高并发的情况下,这个redis的缓存时间失效,
导致redis中这个热点key中大量的请求打到数据库上,导致数据库压力过大导致数据库崩了。
解决方案
1让这个缓存永远不过期【这样会占用空间】
2使用分布式锁【最好的方法】
就是大量的用户发送请求访问redis缓存中的数据时,如果有的话就返回给用户,
如果redis缓存中的热点key没有该数据,就会去请求数据库,在请求数据库的同时加上分布式锁【synchronized+双重校验机制】,
这时候就只有一个线程能够抢到,然后将去数据库进行查询并将结果同步到redis缓存数据库中,以后就不用查询数据库了。