Redis的删除,过期,击穿,穿透,雪崩
Redis里面的RedisTemplate.delete()方法的原理是:
1.RedisConnection 创建redis的连接
2.会去执行命令 createCommand(type,param)
3.程序启动的时候,会自动执行命令,redis1服务器会删除内容。
Redis的删除策略:
1.定时删除:存入的Key的时候设置了过期时间,到时间了就会删除,这里的好处是内存占用低,坏处是,多次调用CPU执行操作。
2.惰性删除:存入的Key设置了过期时间,到时间了不会删除,下次发现过期了,再删除,好处是:减少cpu的执行操作,坏处是内存占用高
3.定期删除:隔一段时间删除过期的key,是前面两种方法的折中的做法,内存占用不那么高,cpu调用次数也不那么高。
Redis与DB在高并发的情况下,遇到的击穿,穿透,雪崩
1.击穿:当大量请求过来,Redis没有这个Key,或者Key过期了,请求直接到DB,造成击穿。
2.穿透:当大量请求过来,Redis里面没有,DB里面也没有,造成穿透
3.雪崩:当大量的请求过来,Redis没有这个Key,或者过期了,直接请求到DB,造成雪崩。
1.1击穿的解决办法:由于Redis是单线程,并发线程全部访问Redis,Redis 的key过期淘汰,通过setnx命令实现锁机制。
set key value a:ex 过期时间,s
b:px 过期时间 ms
c:NX 不存在的key,可设置值
d:XX 存在的key,可设置值
比如:
set age 20 NX EX 60 会返回 1 执行成功
set age 30 NX EX 60 会返回0 没有执行成功
再次查看
get age 返回20
这里就可以看出,当使用NX,如果不存在这个key,那么会赋值,如果存在就不会赋值,利用这一点实现了分布式锁,就是同一个key进来只能获取到同一把锁。
1.2 解决方法:设置热点的Key不过期
1.3 多线程执行的时候,分为两部分,一部分执行成功,一部分睡眠,先用lock.lock()加锁,然后再执行,执行成功后,睡眠的线程再执行,如果执行时间太长会造成死锁,DB访问时间大于锁过期时间会造成阻塞,这个时候需要重启一个线程,查询锁是否过期,刷新锁的过期时间。
2.1击穿的解决办法:缓存空对象,布隆过滤器,DB的数据先转换到一个标记的map中,请求也转成一样的格式,先判断Map中有没有,没有则返回,有则去redis查数据。
3.1雪崩的解决方案:所有的请求设置随机睡眠时间,配合击穿的解决方案,在访问时,通过set NX
实现锁机制,把Redis的key设置成随机的过期时间。