redis缓存穿透、击穿、雪崩

缓存穿透、击穿、雪崩

原文:https://mp.weixin.qq.com/s/_sqGyTvMphOLPpbSCLh0Yw

总结,请求绕过redis,直接作用到mysql上

雪崩:key大面积失效(定时任务刷新缓存,key的过期时间相同,某个时间点全部失效)

解决方案:失效时间都加个随机值避免同一时间大面积失效

场景:app首页数据,所有首页的Key失效时间都是12小时,中午12点刷新的,我零点有个秒杀活动大量用户涌入,假设当时每秒 6000 个请求,本来缓存在可以扛住每秒 5000 个请求,但是缓存当时所有的Key都失效了。此时 1 秒 6000 个请求全部落数据库,数据库必然扛不住

 

穿透:用户恶意使用不存在的key,则请求会到达数据库(如果这个用户并发一直请求就会。。)

解决方案:代码层做好数据效验

场景:使用不存在的用户id,如-1,请求接口

 

击穿:一个Key非常热点,在不停的扛着大并发,大并发集中对这一个点进行访问,当这个Key在失效的瞬间,持续的大并发就穿破缓存,直接请求数据库

解决:将key设置成永不过期,或者自动续期
解决方案二:如果缓存必须更新,加锁,代码加锁后,10万请求,只有一个进入先判断缓存不再,就查询数据库,并更新缓存,接下来释放锁,其他请求就能进来了,并且不需要查询数据库
这个锁最好使用redission分布式锁

 分布式锁(官方推荐redisson)

maven

<!-- https://mvnrepository.com/artifact/org.redisson/redisson -->
<dependency>
    <groupId>org.redisson</groupId>
    <artifactId>redisson</artifactId>
    <version>3.12.5</version>
</dependency>

springboot项目

<!-- https://mvnrepository.com/artifact/org.redisson/redisson-spring-boot-starter -->
<dependency>
    <groupId>org.redisson</groupId>
    <artifactId>redisson-spring-boot-starter</artifactId>
    <version>3.12.5</version>
</dependency>

redisson官方中文文档

 https://github.com/redisson/redisson/wiki/%E7%9B%AE%E5%BD%95

redis实现

key是k,value是v

命令行

#NX是不存在才设置值(原子性的操作),ex是存在才设置值

set k v NX 

 代码

 

问题1:执行业务时出现异常(或者断电导致服务停止)未执行删除锁操作,导致死锁。之后的所有请求都进不来

解决:加锁的同时设置锁的过期时间(不同时进行还是会死锁,可能加完锁还没设置过期时间断电导致)

问题2:业务执行时间过长,导致锁过期,下一个请求进来之后正执行业务时,第一个线程业务执行完毕,将前一个的锁删除掉了

解决:加锁时,加上唯一ID去标示值(但是判断是否是自己的锁和删除锁必须同时执行,否则删除锁时,当前线程的锁失效了,下一个线程锁上了,就把下一个锁给删除了)

但是这个原子操作需要写脚本!!

 

posted @ 2020-05-04 09:56  createcoc  阅读(283)  评论(0编辑  收藏  举报