缓存雪崩
举个例子,例如在双十一中,一点进去。访问量大,所以它很多数据是放在redis区缓存起来,对应redis的100个key。然后假设设置缓存失效时间是三小时。当双十一期间,购物超过这个三小时之后。这个首页的redis缓存会在一瞬间全部失效,导致所有的请求都会打到这个数据库上,造成这个数据库相应不及时而挂掉。这个时候呢,首页没办法再继续对外提供服务
那么缓存雪崩它解决方案有以下几种:
1、第一个就是设置这个首页缓存的失效时间,让他不要在同一时间失效。在我们设置这个缓存的时候,随机初始化他这个失效时间。这样的话所有的缓存就不会在同一时间失效。
2、还有redis一般都是集群部署的,我们把这些热点的key放到不同的节点上去,让这些热点的缓存平均的分布在这个不同的redis节点上。(简单就是多个redis多个请求)
3、最暴力的方法,就是不设置缓存失效的时间,让他永远不失效。
4、跑定时任务,让他定时的刷缓存。比如我这个缓存设置了三小时时效,那么我在失效之前,就把这个redis缓存给他重新跑进去。然后再设置三小时。不断地用定时任务去刷新,这个缓存就不会失效。
缓存穿透
举个例子,比如说老哥自己开发了一个网站,然后这个网站非常地火爆,动了某些人的蛋糕,然后遭到疯狂的攻击就是采用缓存穿透。大家都知道数据库主键从0开始递增,没有负数。那么黑客就是利用这一点,他不断地利用这个id小于零地这个参数给它发请求。我把数据库里面,所有地数据都放到了redis,但是他用id小于零地数来请求,redis里面没有这个id,这样地话redis就查不到这个结果,一旦这个redis查不到这个结果,就会去数据库中查。那么就会造成请求不断地打到数据库上。因为中间redis这层是不能拦截这样的数据,这个redis直接被这种数据给穿透。
就一直写这个id为-1的自动化脚本即可
解决办法
1、这个请求如果穿透这个redis直接到这个数据库,我数据库无论查出什么结果,是空值还是有值,都会缓存到redis里去。这样他下次用同一个参数来发请求的时候就不会穿透这个redis。但是他可能会换不同的参数。
2、把他这个ip拉黑,但是他也可能换不同的ip
3、对参数的合法性检验,在判断这个参数不合法的时候,直接return掉
4、布隆过滤器。布隆过滤器可以用于缓解缓存击穿问题。它被放置在缓存之前,作为一个快速的预过滤器。当一个请求到达时,首先经过布隆过滤器。如果布隆过滤器认为请求对应的数据肯定不在缓存中,就可以直接拒绝这个请求,而无需查询缓存或数据库。这样就可以避免大量请求落到数据库上,减轻了数据库的压力。
缓存击穿
我们还拿双十一来举例 。比如很多人在九点的时候准时拍卖这个鞋。这个鞋的数据被放到了redis缓存里,对应这一个redis一个缓存的key。当这个鞋的缓存key超过缓存时间突然失效了,导致大量的请求查询不到这个数据
解决方案
1、让缓存永远不过期肯定不好
2、分布式锁。如果是当体应用的话就可以使用分布式锁。首先大量用户访问这个redis请求数据,如果有的话就会返回给用户。如果redis里面的数据为空的话,他就会请求这个数据库去请求数据。我们就在这个请求数据库这一步给他上锁。那么这个时候就只有一个线程,能抢到这个锁,那么对数据库的压力就非常小。当他查询到这个数据之后,会把缓存重新写道这个ride里面去。其他没有抢到锁的线程,先让他睡几毫秒,然后再重新去redis里面去查询这个数据。
分布式锁具体怎么实现?可以用zookeeper或者redis去实现这分布式锁