缓存穿透
1.应用服务压力变大了。
2.redis的命中率降低。
3.一直访问数据库,导致数据库的崩溃。
产生的原因是伪造的数据访问!!
1.redis查询不到数据
2.出现了很多的非正常的url访问
3.多为恶意攻击
如何解决?
1.对空值缓存:将空的值缓存,设置一定时间,在缓存区设置一个空的key,当收到恶意的空请求的时候就可以在缓存层面给予回应,从而减少对数据库的访问。
2.设置可访问的名单:(白名单)使用bitmaps来判断,对不符合的进行拦截,效率低。
3.采取布隆过滤器:也是使用的bitmaps但是其算法的支持效率比较高,但是有误差。
4.进行实时监控:当发现Redis命中率急剧降低的时候要排查访问的对象和对数据,配合运维的人员设置黑名单进行限制。
缓存击穿
现象
1.数据库的访问压力瞬间增大。
2.redis里面没有出现大量的key过期
3.redis正常使用
发生的原因
redis中的某一个key过期了,发出的请求大量访问使用这个key
解决办法
1.预先设置热门数据:将这些数据的key时长增加。
2.适时调整:现场监控,调整key的过期时长。
3.使用锁:没有数据就拒绝访问,等有数据的时候在让访问,但是效率很低。
缓存雪崩
现象
1.数据库压力变大
2.服务器崩溃
原因
1.在某个时间段内出现了大量的key集中过期的情况
解决办法
1.构建多级缓存架构如:ngix+reids+其他缓存
2.使用锁或者队列:不适合高并发,容易卡死。
3.设置过期标值,更新缓存,设置提前量,如果发生过期就会触发通知线程后台去更新实际key的缓存。
4.将缓存的失效的时间分散开来,加上一个随机值,以防大量的key失效,导致缓存雪崩。
分布式锁
是什么?
单独的服务器是一个单独的操作,现在是很多redis在一块操作,引入分布式锁是解决在集群环境中锁的实现。让所有的都知道的锁。共享锁?如何防止锁的错误使用?
怎么实现?
三种方式:
数据库
redis 性能最好
zookeeper 可靠性最高
setnx 命令就是一种这样的锁,握住锁后只能添加一次。
对于分布式锁要设置锁的过期时间,防治锁锁死不放开!(上厕所锁上了门,然后睡着了!!)
锁坏了如何处理?(上厕所然后锁坏了??)没法设置时间了…
解决办法:上锁的时候设置过期时间。–可以使用事务来做嘛?
No!!
因为redis里面的事务不能保证原子性。
因为锁是公用的,所以会出现一人操作其他人锁的现象,所以我们使用UUID的方法,给每一个锁设置一个UUID绑定后,只有自己才能够释放自己的锁。
所以就是一个共用的锁,但是分人,只有特定的人才能打开和关闭。(我在想这样是不是把共用的这个特性整没了?)
删除操作中的原子性问题!
上锁–>具体操作–>释放锁del(删除的过程中,发现key过期了,但是删除仍继续)----这个锁的释放会释放其他线程的锁。会互相的干扰,从而影响结果。
这是个很巧的事件,我要释放锁的时候正好过期了,那么我要释放那个锁呢?因为前面我已经上锁了,也就是验证过了,所以这个锁就处于了游离状态,会干扰其他的锁。(上厕所的时间到了,我推门而出,按照规则我应该开一个锁,不然这个过程不完整,但是这个锁因为过期自己开了,所以我就要开其他的厕所门了,从而引起了混乱!!)
如何解决redis中的原子性问题?
LUA脚本支持原子操作,可以将锁的这个过程变成脚本语言,从而保证原子性,解决问题。
对于里面的知识认识还比较浅显,不断的整理笔记加深大脑的印象,加油!