1.缓存雪崩
啥是缓存雪崩?
很多电商平台的首页或是一些热点数据都会使用Redis去做缓存,而这些缓存是用定时任务去刷新的,这样就带来一个问题。比如说:
马上就要到双十一零点了,我们把一些热销的商品放入缓存,并设置失效时间为一个小时,也就是当双十一凌晨一点的时候,这批商品同时全部失效,就在失效的那一瞬间,大量的用户请求全部打到了数据库上,数据库哪能承受这么大的压力,立马就崩了。尽管可以重启数据库,但依旧还是会被新的流量打崩。
怎么解决缓存雪崩呢?
最简单的方法就是给缓存设置失效时间的时候,给他们加上一个随机因子,让他们不在同一时间失效。
setRedis(Key,value,time + Math.random() * 10000);
2.缓存击穿
啥是缓存击穿?
看名字我们就可以知道,他是针对于单个key。其实缓存击穿和缓存雪崩有点像,俗话说:雪崩的时候,没有一篇雪花是无辜的,指的就是缓存雪崩的时候,同时大面积失效的key他们都是有“罪”的,而缓存击穿是指一个Key非常热点,不停的扛着大量的请求,大量的并发访问几乎都在这个Key上,当这个Key失效的一瞬间,大量的并发请求直接落在了数据库上,从而将数据库打崩。这个动作看上去就像是“击穿”。
咋解决呢?
最直接的方法就是将热点Key不设置失效时间,还有个方法就是加锁,当查询热点Key的时候加上互斥锁,这样就保证同一时间只有一个请求能访问这个Key。
3.缓存穿透
啥是缓存穿透?
缓存穿透是指查询一个数据库一定不存在的数据。正常的使用缓存流程大致是这样的,数据查询先进行缓存查询,如果key不存在或者key已经过期,再对数据库进行查询,并把查询到的对象,放进缓存。如果数据库查询对象为空,则不放进缓存。
想象一下这个情况,如果传入的参数为在数据库中不存在,会是怎么样?就会每次都去查询数据库,而每次查询都是空,每次又都不会进行缓存。假如有恶意攻击,就可以利用这个漏洞,对数据库造成压力,甚至压垮数据库。即便是采用UUID,也是很容易找到一个不存在的KEY,进行攻击。
如何解决?
接口层增加校验,如遇到数据库不存在或是不合法的参数,直接return,不需要再去访问数据库。常见的就是用户校验,参数校验等。 还有个方法就是使用Redis提供给我们的布隆过滤器,这个能很好地预防缓存击穿。原理也很简单就是利用高效的数据结构和算法快速判断出你这个Key是否在数据库中存在,不存在你return就好了,存在你就去查了DB刷新KV再return。