缓存雪崩
在某一个时间存在大量的缓存key失效
解决办法
1.有效期一直————>给每一个数据加上水机有效期
2.redis挂掉了—————>使用redis集群,分摊key的存储

引出redis集群的hash一致性算法
看我的geecache里面有讲解,需要用到哈希环,传送门
3.不设置缓存时间,不太建议
4.使用定时任务刷新快要过期的缓存,进行重置
缓存穿透
访问redis内不存在的缓存,造成直接查询数据库。给数据库造成压力。比如id=-1,一般这种在非法访问场景。非正常数据请求(黑客)
缓存穿透不能避免,因为数据缓存是无解问题(永远不能保证一致 )不怕低频率穿透,怕高频率的。
解决办法
1.使用布隆过滤器
2.非法访问,业务直接抛出
3.这种异常key,也进行缓存存储。防止后续频繁访问数据库
4.ip拉黑
布隆过滤器:

过滤器放在这个位置,讲道理放在越前面越好,但是可控性得不到保障。
过滤器里面放所有的缓存吗???
不是,因为过滤器的缓存也很紧张
布隆算法:通过一定的错误率来换取空间
这句话怎么理解

100亿个数据才1.1g左右
原理
用bit数组来标识数据

布隆算法是由于哈希冲突导致的错误,宁可错杀三千不可放过一个
所以我们这里就是为了降低哈希碰撞的概率提出两个办法
1.加大数组长度
2.增加哈希函数的个数
第二个方法解释:

假设我们一个碰撞的概率是百分之1,我们计算出三个地方的值都为1的概率就很低了,那么概率近乎是百分之一的三次方。大大降低了碰撞概率。
但是并不是越多越好!!!!因为越来越多就会到最后错误率一定百分百!!!
所以函数的个数需要参考数组的长度
算法弊端:要是我们删除数据怎么办?
一个位置上的1可能代表几个数的哈希值,那么我们解决办法就是搞一个计数器,在第二纬度

如果计数器的值为0,那么我们可以放心的把bit数组位置上面的值变为0
缓存击穿
业务并发量大时,访问单一缓存key。并发查询同一数据,单一缓存key,由于过期失效。造成大量请求直接访问数据库。(拍卖场景,一般公司不需要解决,因为没有那么热门的数据让他击穿!!!!!! )
解决办法
1.增加分布式锁
2.根据业务,判断是否需要设置为永不失效
分布式锁详解:
背景,都抢一个厕所:

上锁三个条件:
1.共享资源
2.多任务请求
3.共享资源互斥
必须三个条件都满足才会上锁
死锁:
假设马老师在厕所,但是锁门后休克了,其他人就不能获取这个厕所,这就发生了死锁
死锁怎么解决:
搞一个监听,如果这把锁存在的时间超出设定的最大值,我们就会把他干掉(周老师一直不应答就打120)
但是又引来新的问题:timeout(监听)时间设置多长??
设置短了,导致没做完就被干掉了,厕所上一半就被拉出来。(现实场景:一票多卖)。设置长了,导致资源浪费
所以一般基于zookeeper来实现分布式锁!!!
暂时不讲,因为我也不太懂
那么基于分布式锁我们怎么做?
请求先给nginx,nginx根据分发策略分发,然后查询redis数据,如果失效了,那么我们就弄一把分布式锁,抢到了先缓存在redis中,其他的就直接查redis

假设又1000条请求,只需要缓存一条就够了,其他999条可以查询